Uncaught exception 'RedisException' with message 'Connection closed' on session_start() call #184

Open
dmitry-saritasa opened this Issue May 17, 2012 · 49 comments

Projects

None yet
@dmitry-saritasa
  1. installed redis 2.4.13 on server1
  2. installed phpredis 2.2.1 on server2
  3. updated my php.ini on server2 to have sessions in redis instead of files

session.save_handler = redis
session.save_path = "tcp://10.100.100.50:6379" - this points to server1

  1. restarted apache
  2. phpinfo() shows config looks into redis for sessions
    http://screencast.com/t/FMnHMnxc
  3. when I open my backend on server2 that immediately sets the session (session_start)

I get the following error:

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in /home/www/sites/production/html/backend/connect.php:31 Stack trace: #0 /home/www/sites/production/html/backend/connect.php(31): session_start() #1 /home/www/sites/production/html/backend/controller.php(5): require_once('/home/www/sites...') #2 {main} thrown in /home/www/sites/production/html/backend/connect.php on line 31

Fatal error: Exception thrown without a stack frame in Unknown on line 0

  1. Connections from my PHP server (server2) to Redis server (server1) goes just fine.

I can use redis-cli to set the variable on PHP server (server2)
and I see it using redis-cli on REDIS server (server1) using "monitor" command

so firewall is not the issue

any ideas?

I saw this bug
#134

and that script
$r = new Redis();
$r->connect('10.100.100.50:6379');
$r->incr('foo');
var_dump(
'Redis::get("foo") -> '. $r->get('foo'),
$r->info()
);

works just fine

not sure if it's got back in the src again somehow.

@dmitry-saritasa

anybody?

@michael-grunder
Member

Hey,

I will attempt to test this but I don't actually use any of the phpredis session stuff, or php sessions at all for that matter. Looking through the code, the exception "connection closed" is only thrown on a socket error when writing to the socket.

Are you sure you can connect to the Redis server from within a script executed wihin apache (vs. cli)?

@dmitry-saritasa

Yes I verified a script within apache (simple http://host/redis.php) is working and I'm seeing activity when using redis-cli on redis host.

$r = new Redis();
$r->connect('10.100.100.50:6379');
$r->incr('foo');
var_dump(
'Redis::get("foo") -> '. $r->get('foo'),
$r->info()
);

works

@dmitry-saritasa

Hi Michael,

were you able to replicate the issue?

thanks,
Dmitry

@michael-grunder
Member

@saritasa Sorry, been a bit mental at work. I haven't set up a test environment for this just yet. I'm going to do my best to set something up this evening.

@dmitry-saritasa

Sorry to bug you - Any news?

@michael-grunder
Member

@saritasa Hey, I haven't had the time to test it yet, but I may have noticed something. I see from your original post that it is showing this (in your attached image):

session.save_path /var/lib/php5

Are you sure there isn't a duplicate session.save_path in your php.ini?

@srsbiz
srsbiz commented Jun 23, 2012

I had the same issue, but for me the problem was trailing slash, that i copied from http://redis4you.com/articles.php?id=001&name=Redis+as+session+handler+in+PHP

Looking at your configuration, it shouldn't be issue for you, but it won't hurt to check if there is not any trailing slash.

@KocTbIJIb

Same problem:
session.save_path doesn't changes according to php.ini value

@nicolasff
Contributor
@thomascrown

@nicolasff I set up my php.ini exactly like in your suggested post - research around a bit - but I am still getting the same issue when trying to start a session:

Warning: Unknown: Failed to write session data (redis). Please verify that the current setting of session.save_path is correct (tcp://localhost:6379) in Unknown on line 0

I can write and retrieve data normally, as per the following code:
$redis = new Redis();
$redis->connect('localhost', 6379);
$test = $redis->set('testvar', 'itworks');
$test = $redis->get('testvar');
echo (print_r($test,1));

EDIT: Should note that I am using PHP 5.4.4 with Nginx + PHP-FPM.
I solved the problem by changing session.save_path to "localhost:639" = so without the tcp://
The post that you mentioned indicated taking of the trailing / after the port, but that alone didnt work.

Hope this helps anyone else having the same problem

@nicolasff
Contributor

Thanks Thomas, I will try to reproduce it tonight.
Does this issue happen every time, or just from time to time?

Nicolas

On 9 July 2012 16:49, thomascrown <
reply@reply.github.com

wrote:

@nicolasff I set up my php.ini exactly like in your suggested post -
research around a bit - but I am still getting the same issue when trying
to start a session:

Warning: Unknown: Failed to write session data (redis). Please verify that
the current setting of session.save_path is correct (tcp://localhost:6379)
in Unknown on line 0

I can write and retrieve data normally, as per the following code:
$redis = new Redis();
$redis->connect('localhost', 6379);
$test = $redis->set('testvar', 'itworks');
$test = $redis->get('testvar');
echo (print_r($test,1));


Reply to this email directly or view it on GitHub:
#184 (comment)

@thomascrown

Thanks for the reply - the issue was hapenning every time, however since then I have edited the post with a solution that I arrived at. By taking tcp:// our of the session path (im using php5.4.4) I was able to get sessions working

Only question I have though is, does this affect cases where you would use redis to control sessions over multiple servers? From your config in the readme, you had mentioned using weights with different hosts... etc. and indicated that the use of tcp:// was mandatory to get this working....

@nicolasff
Contributor

Hmm, I'm no sure why that wouldn't work with PHP 5.4.4.
I'll install it and try to get to the bottom of this issue; tcp://
certainly works on PHP 5.3; it uses the PHP url parser to extract these
parameters and the "scheme" (e.g. tcp://, http:// etc. is required as far
as I know.)

Nicolas

On 9 July 2012 17:42, thomascrown <
reply@reply.github.com

wrote:

Thanks for the reply - the issue was hapenning every time, however since
then I have edited the post with a solution that I arrived at. By taking
tcp:// our of the session path (im using php5.4.4) I was able to get
sessions working

Only question I have though is, does this affect cases where you would use
redis to control sessions over multiple servers? From your config in the
readme, you had mentioned using weights with different hosts... etc. and
indicated that the use of tcp:// was mandatory to get this working....


Reply to this email directly or view it on GitHub:
#184 (comment)

@thomascrown

Thank you very much for looking into it - and also, thank you for all your hard work in creating this amazing program

@nicolasff nicolasff closed this Jul 9, 2012
@nicolasff nicolasff reopened this Jul 9, 2012
@nicolasff nicolasff added a commit that referenced this issue Jul 9, 2012
@nicolasff nicolasff Fix host|file condition in session backend.
Should address #184. Adding a slash at the end would make phpredis
consider "/" as the path and ignore the host. Having a host name now
takes precedence over having a file name.
f3dff08
@nicolasff
Contributor

@thomascrown I've found an issue and updated phpredis, I would appreciate if you could give it a try.

@thomascrown

@nicolasff Hi again - I fired up the fixed version and it did the trick - thank you for the fast response and solution.
session.save_path = "tcp://localhost:6379?weight=1" now works

@nicolasff
Contributor

Great, thanks!

@nicolasff nicolasff closed this Jul 9, 2012
@xuguotao

@nicolasff Hi,I find Uncaught exception 'RedisException' with message 'Connection closed' on session_start() call in php 5.4.6,can u help me?

@nicolasff
Contributor

@xuguotao could you post some sample code to reproduce the issue?

Thanks.

@xuguotao

@nicolasff , thank you for the fast response.
My php version is PHP 5.4.6 (cli) (built: Aug 20 2012 11:30:48)
My redis server version is 2.4.17
My phpredis version is 2.2.2

this script :

$redis = new Redis();
$redis->connect('localhost', '6380');
$redis->set('t', 's');
echo $redis->get('t');

it`s work....

but that script

ini_set("session.save_handler","redis");
ini_set("session.save_path","tcp://localhost:6379"); //or "localhost:6379" or add "/"
session_start();
$_SESSION['redis'] = "aaaaaa";
echo session_id();
echo $_SESSION['redis'];

Exception print:
Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in /var/www/html/test.php:10 Stack trace: #0 /var/www/html/test.php(10): session_start() #1 {main} thrown in /var/www/html/test.php on line 10

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in [no active file]:0 Stack trace: #0 {main} thrown in [no active file] on line 0

thanks again~

@nicolasff
Contributor

@xuguotao Your call to connect uses port 6380, and your session handler port 6379. Could this be why the session handler can't connect to Redis?

@xuguotao

@nicolasff ,i'm sorry,the demo script is my clerical errors,my test script and 'ini_set' both are uses port 6380,the result still wrong...

ps:
my make test result:
PHP : /usr/bin/php
PHP_SAPI : cli
PHP_VERSION : 5.4.6
ZEND_VERSION: 2.4.0
PHP_OS : Linux - Linux guotao.server 3.6.1-1.fc17.x86_64 #1 SMP Wed Oct 10 12:13:05 UTC 2012 x86_64
INI actual : /home/xuguotao/Soft/phpredis/tmp-php.ini
More .INIs :
CWD : /home/xuguotao/Soft/phpredis
Extra dirs :
VALGRIND : Not used

@gajus
gajus commented Apr 21, 2013

I am getting the same error using:

session.save_handler = redis 
session.save_path = "unix:///var/run/redis/redis.sock?persistent=1&weight=1&database=0"

I've enabled debug level logging, though there is nothing in the error log.

PHP Exception

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in /var/www/dev/gajus kuizinas/2012 10 01 anuary/index.php:2
Stack trace:
#0 /var/www/dev/gajus kuizinas/2012 10 01 anuary/index.php(2): session_start()
#1 {main}

Next exception 'RedisException' with message 'Connection closed' in /var/www/dev/gajus kuizinas/2012 10 01 anuary/index.php:2
Stack trace:
#0 /var/www/dev/gajus kuizinas/2012 10 01 anuary/index.php(0): session_start()
#1 {main}
  thrown in /var/www/dev/gajus kuizinas/2012 10 01 anuary/index.php on line 2

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in [no active file]:0
Stack trace:
#0 {main}
  thrown in [no active file] on line 0

@andyfleming

When I set all my settings in php.ini it works fine for me, but when I set it on the fly (in a PHP script) it doesn't.

ini_set('session.save_handler','redis');
ini_set('session.save_path','tcp://10.0.0.1:6333?weight=1');

Warning: Unknown: Failed to write session data (redis). Please verify that the current setting of session.save_path is correct (tcp://10.0.0.1:6333?weight=1)) in Unknown on line 0

@michael-grunder
Member

Hey there,

This works just fine for me. It could be a longshot but you are using port 6333 in your example, but the error is reporting port 6379. Could it possibly be a typo?

Cheers,
Mike

@andyfleming

@michael-grunder — Typo. I was changing the IP and port from what I'm actually using in my code. In reality, in my code, it matches what I tested in php.ini.

@andyfleming

@michael-grunder — However, I also had a second typo. An extra ) was in my string. FAIL.

Works now. 👍

@zyuhel
zyuhel commented Jun 21, 2013

Would like to see let it here. May be it will help some one as it have done for me. Exception when connected to socket could appear if apache/php user hasn't got rights to write to redis sock, so please check it :)
Great module that works great

@enumag
enumag commented Aug 19, 2013

I've the same problem. None of the solutions described in this issue worked for me. I'll post more information here when I have some time.

@enumag
enumag commented Aug 19, 2013

Caching to Redis works just fine, the only problem is sessions.
I've tried the test script from @xuguotao:

ini_set("session.save_handler","redis");
ini_set("session.save_path","tcp://localhost:6379"); //or "localhost:6379" or add "/"
session_start();
$_SESSION['redis'] = "aaaaaa";
echo session_id();
echo $_SESSION['redis'];

Sure enough, I get this output:

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in /www/hosting/m33.cz/redis2/www/index.php:7
Stack trace:
#0 /www/hosting/m33.cz/redis2/www/index.php(7): session_start()
#1 {main}
  thrown in /www/hosting/m33.cz/redis2/www/index.php on line 7

Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in [no active file]:0
Stack trace:
#0 {main}
  thrown in [no active file] on line 0

My PHP version is 5.4.17 and I'm using latest master branch of PhpRedis. I've tried it both with and without igbinary and got the same results.

@michael-grunder What other information should I provide? Also can you reopen this issue?

@nicolasff nicolasff reopened this Aug 19, 2013
@devdemi
devdemi commented Sep 6, 2013

Same problem with php-redis 2.2.3 and PHP 5.3.27-1~dotdeb.0. I tried different urls in session.save_path but i still get error.

@enumag
enumag commented Sep 6, 2013

@devdemi: I've solved it with custom session handler. This one is for Nette framework but you can easily modify it for plain PHP.

@yubingxing

I have the same problem with php-redis master branch and php 5.4.9,

@paulsbroomfield

Hi,

Please double check your config files.

check your

/etc/php.ini

add the following

session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"

also scroll down your php.ini and make sure there are no more session.save_path's as they will override your settings, just comment them out.

Also if you're on Centos or the like check your

/etc/httpd/conf.d/php.conf

as well. Check the following are commented out

#php_value session.save_handler "files"
#php_value session.save_path    "/var/lib/php/session"

restart apache and you should be good to go.

ta,

@luisbarrueco

Hi, I'm using phpredis 2.2.3, and I get the same error, but just from time to time. I'm running on amazon EC2 and my Redis server is an Elasticache node.

@michael-grunder
Member

Hey,

Generally this has to do with pconnect and/or timeouts on the PHP or Redis side of things. It can happen when a connection is idle for too long and either side resets the connection. phpredis does have reconnect logic, but sometimes that doesn't work.

What are your timeouts, etc?

Cheers,
Mike

@luisbarrueco

Sorry, more info below:
The problem occurs in the session_start() call, and we don't have configured persistent connections for sessions (as I read it was still experimental). So, the "connection closed" must refer to a connection that was just established.
The redis server has the "tcp-keepalive" parameter disabled, and the "timeout" in 0 (connections don't timeout).

I just began to see a pattern, with these errors happening around the time new webservers launch or are terminated, so this might be an external network issue after all... I'll keep you posted.

Thanks

@michael-grunder
Member

Thanks for the update. Please post anything you find in this issue thread and maybe we can track it down (if it is in phpredis).

Cheers!
Mike

@andrewtch

Same error.

PHP 5.4.21-1~dotdeb.0 (cli) (built: Nov 2 2013 21:32:49)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans

ii redis-server 2:2.6.16-1~dotdeb.0 amd64 Persistent key-value database with network interface

@andrewtch

Nevermind, my bad.

This sometimes happens if session.save_path is declared via php_admin_value in apache configs, therefor whatever you do in your code, you get "Connection closed".

My advice would be to add current session_save.path to the exception text.

@jazzfog
jazzfog commented Apr 30, 2014

I had the same problem, but i found out that PHP script itself had session configuration ini_set('session.save_path', '/tmp/session'); and after I removed this (not needed anymore) configuration - everything works just perfect.

@drpain
drpain commented Jan 22, 2015

I use Vagrant boxes for my dev, be sure to check any custom .ini files for session vars:
grep -i "session." /etc/php*

After you commented out all the normal session vars and only have the redis ones, restart php:
sudo service php-fpm restart

You should only really have these two in you're php.ini once done:
session.save_handler = redis
session.save_path = "tcp://localhost:6379"

And you can then see if redis is hit by running:
redis-cli monitor

@STASiAN
STASiAN commented Jun 4, 2015

Same error

rpm -qa|grep redis
redis-2.8.19-1.el6.remi.x86_64
php-pecl-redis-2.2.7-1.el6.remi.5.4.x86_64

php -i|grep save_handler -A1
session.save_handler => redis => redis
session.save_path => tcp://localhost:6379?database=9 => tcp://localhost:6379?database=9

PHP Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in test.php

content in test.php:

session_start();

@Nenillo
Nenillo commented Jun 6, 2015

Same for me as the message above but in Debian 7, with pecl redis extension (2.2.7). Tried with tcp://, without tcp, with unix socket... always getting the same error message:

PHP Fatal error: Uncaught exception 'RedisException' with message 'Connection closed' in ...

session.save_handler = redis
session.save_path = "unix:///var/run/redis/redis.sock?persistent=1&weight=1&database=0"

Tried setting this in php.ini and .htaccess and I always get the same "Connection closed" error message.

Tried also compiling the develop branch with no luck.

EDIT: Had some additional session.save_path set with ini_set that was breaking the config. Removed it and all works fine now. Thanks!

@modoki
modoki commented Jul 10, 2015

Please forgive me my lousy English.

A person using php-fpm requires attention.

Contents of php.ini are /etc/php-fpm.d/www.conf and are overwritten.

For example,
php_admin_value[session.save_path] = /var/lib/php/session

Please execute the next program on WebServer.(not php-cli)

<?php
var_dump(ini_get("session.save_handler"));
var_dump(ini_get("session.save_path"));
@akiuni
akiuni commented Jul 11, 2016

Hi

this worked for me both on unix and TCP sockets, session.save_path set in php.ini or fpm php_admin_value as well.

Important point : For unix socket, the .sock file need to be writable by php-fpm user

Bests

@Committing

The fix for me was to just restart Redis.

service redis restart

@yeszao
yeszao commented Jan 4, 2017

In my case, session.gc_maxlifetime was the reason. I get the error because session.gc_maxlifetime was set to 144000000000. it will overflow and become a non-positive expire time passed to Redis.

These just delete the key, see: https://redis.io/commands/expire.

I had tested that the maximum expire time in Redis was 2147483647 (0x7fffffff).

So, I solved this issue by set session.gc_maxlifetime = 3600.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment