INCR works different on different versions of redis. For example:

  SET test ""
  INCR test
  GET test

returns "1" in redis 3.0.7 and lower versions

but shows an error (error) ERR value is not an integer or out of range when using redis 3.2.3 or 3.2.5 I did not see information about such breaking changes of INCR in release notes, is it a bug or expected behavior?

Comment From: antirez

Hello, it was a bug in Redis 3.0, but we clearly failed to document it. I'll update the 3.2 release notes. Thanks.

Comment From: xplicit

In version 2.4.9 the sequence SET test "" INCR test also returns "1", this behavior was not introduced in v3.0 it have been there for a long time, but in version 3.2 it was changed to throw an error instead of treating empty string as zero.

We use empty strings to hold zero values for integral types and this change does not allow to switch redis to newer version without migrating data. We can do this if holding empty string instead of "0" for integers is wrong, but would be great to know which types we should convert also. Should we convert decimals/doubles or any other types? Do they have redis special underlying types like integer have got?

Comment From: ganlvtech

Commit https://github.com/redis/redis/commit/23791828f1cd54ebea95d8c860058e55ff28aebf caused this issue.

Originally any empty string to long long conversion will be OK and the result is 0. Now they will raise an ERR. You should handle them by yourself

Related issue https://github.com/redis/redis/issues/3333 .

This make the following command SET foo and return error, instead of SET foo and then DEL it immediately.

SET foo bar
EXPIRE foo ""

Summary

Redis >= 4.0 -> ERR Redis < 4.0 -> OK

Comment From: oranagra

@ganlvtech thank you for the detailed comment. anyway, this is water under the bridge now, bug is fixed long ago.

redis 6.0:

127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> expire foo ""
(error) ERR value is not an integer or out of range
127.0.0.1:6379> get foo
"bar"

Comment From: ganlvtech

Some unexpected thing happened when we decide to migrate an Redis 2.8 used for many years to the latest version.


First, some bad code don't check value type.

$redis->set("foo", false);

Because of PHP's auto type conversion, it is same to

$redis->set("foo", "");

And then

$redis->incr("foo");

In redis 2.8: foo will be 1. In Redis 4.0: Error! foo still be "" and error will occured every time INCR is called.

Comment From: itamarhaber

Hello @ganlvtech - apparently you're the first person to report this as well as to be affected by it and the fix in https://github.com/redis/redis/commit/23791828f1cd54ebea95d8c860058e55ff28aebf.

I hope that your system is working now.