Tag Archives: Project practical skills

Springboot startup error: err config is disabled command (Redis Disables Config command)

1. Background description

The project belongs to spring boot, which is always normal. Due to the recent security activity disabling redis’s config command, an error is reported when the project is restarted:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/boot/autoconfigure/session/RedisSessionConfiguration$SpringBootRedisHttpSessionConfiguration.class]: Invocation of init method failed; 
nested exception is org.springframework.data.redis.connection.ClusterCommandExecutionFailureException: ERR config is disabled command; 
nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR config is disabled command; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: ERR config is disabled command; 
nested exception is redis.clients.jedis.exceptions.JedisDataException: ERR config is disabled command

2. Analysis

Check the source code of redishttpsessionconfiguration class (as shown below), and find the input parameter to enable the keyspace notifications function: configurereredisaction.configurereredisaction accepts the injection. The default is new configurenotifykeyspaceeventsaction() in the constructor. Looking at the source code of this class (not posted here), we find that this class is used to configure the “notify keyspace events” function. Then, redis’s config command will be used in the static internal class enablererediskeyspacenotificationsinitializer, Since the config command is disabled, the above exception is reported.

Look at the post-processing condition if (this.configure! =configurereredisaction.no_op) in the static internal class. The solution is obvious here.

The solution is to inject configurereredisaction.NO_OP, do not receive the default configurenotifykeyspaceeventsaction.configureRedisAction.NO_op itself does not do any processing.

private ConfigureRedisAction configureRedisAction;

......

public RedisHttpSessionConfiguration() {
        this.redisFlushMode = RedisFlushMode.ON_SAVE;
        this.cleanupCron = "0 * * * * *";
        this.configureRedisAction = new ConfigureNotifyKeyspaceEventsAction();
    }

......

@Autowired(
        required = false
    )
    public void setConfigureRedisAction(ConfigureRedisAction configureRedisAction) {
        this.configureRedisAction = configureRedisAction;
    }

......

@Bean
    public InitializingBean enableRedisKeyspaceNotificationsInitializer() {
        return new RedisHttpSessionConfiguration.EnableRedisKeyspaceNotificationsInitializer(this.redisConnectionFactory, this.configureRedisAction);
    }
......

static class EnableRedisKeyspaceNotificationsInitializer implements InitializingBean {
        private final RedisConnectionFactory connectionFactory;
        private ConfigureRedisAction configure;

        EnableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory, ConfigureRedisAction configure) {
            this.connectionFactory = connectionFactory;
            this.configure = configure;
        }

        public void afterPropertiesSet() throws Exception {
            if (this.configure != ConfigureRedisAction.NO_OP) {
                RedisConnection connection = this.connectionFactory.getConnection();

                try {
                    this.configure.configure(connection);
                } finally {
                    try {
                        connection.close();
                    } catch (Exception var8) {
                        LogFactory.getLog(this.getClass()).error("Error closing RedisConnection", var8);
                    }

                }

            }
        }
    }

3. Solutions

Inject the default object configurereredisaction.NO_OP, add a configuration item switch to keep unchanged and respond to changes.

package com.abc.test.config;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.session.data.redis.config.ConfigureRedisAction;

/**
 * After disabling Redis' config command.
 * Here when the configuration file redis.disableConfig=true inject ConfigureRedisAction.NO_OP to solve the problem, otherwise it is handled by default
 * @author test
 * @version 1.0
 * @date 2021/12/29 15:44
 */
@Configuration
@ConditionalOnProperty(value = "redis.disableConfig", havingValue = "true")
public class HttpSessionConfig {

    @Bean
    public static ConfigureRedisAction configureRedisAction(){
        return ConfigureRedisAction.NO_OP;
    }
}

Time is pressing, over!