HumanSignal/label-studio · error · ValidationError

Can't connect to Redis server.

Error message

Can't connect to Redis server.

What it means

RedisImportStorageSerializer.validate() instantiates the storage and calls storage.validate_connection(); any exception raised (connection refused, auth failure, timeout, or even the missing-db ValueError) is swallowed and re-raised as this generic DRF ValidationError. It tells you the Redis server was unreachable with the given settings but hides the underlying reason.

Source

Thrown at label_studio/io_storages/redis/serializers.py:29

    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))

    class Meta:
        model = RedisImportStorage
        fields = '__all__'

    def to_representation(self, instance):
        result = super().to_representation(instance)
        result.pop('password')
        return result

    def validate(self, data):
        data = super(RedisImportStorageSerializer, self).validate(data)

        storage = RedisImportStorage(**data)
        try:
            storage.validate_connection()
        except:  # noqa: E722
            raise ValidationError("Can't connect to Redis server.")
        return data


class RedisExportStorageSerializer(ExportStorageSerializer):
    type = StorageTypeField(default=os.path.basename(os.path.dirname(__file__)))

    def to_representation(self, instance):
        result = super().to_representation(instance)
        result.pop('password')
        return result

    class Meta:
        model = RedisExportStorage
        fields = '__all__'

View on GitHub (pinned to 0b49e9b539)

Solutions

  1. Check the server logs / temporarily reproduce with redis-cli -h <host> -p <port> -a <password> -n <db> ping to see the real error.
  2. Verify host, port, password, ssl and db fields in the storage payload are correct.
  3. Confirm network reachability (Docker network, security groups, firewall) between Label Studio and Redis.
  4. If auth is the cause, set the correct password/sentinel settings and retry.

Example fix

// before (failing payload)
{"type": "redis", "host": "redis.internal", "path": ""}

// after
{"type": "redis", "host": "redis.internal", "port": 6379, "password": "secret", "db": 1}
Defensive patterns

Strategy: try-catch

Validate before calling

import redis

def redis_reachable(host: str, port: int, password: str | None, db: int) -> bool:
    try:
        r = redis.StrictRedis(host=host, port=port, password=password, db=db,
                              socket_connect_timeout=3, decode_responses=True)
        return r.ping()
    except redis.RedisError:
        return False

Type guard

def is_valid_redis_config(cfg: dict) -> bool:
    return bool(cfg.get('host')) and isinstance(cfg.get('port', 6379), int) and bool(cfg.get('db'))

Try / catch

try:
    serializer.is_valid(raise_exception=True)
except ValidationError:
    # inspect host/port/password/db, then probe with redis-cli or redis.ping()
    logger.exception('Redis storage validation failed; check host/port/auth/db')

Prevention

When it happens

Trigger: POST/PUT to the storage API creating a Redis import storage whose host/port/password/db do not allow a working redis connection; validate_connection() raising inside the serializer's validate().

Common situations: Redis not running or wrong port; password required but not supplied (NOAUTH); TLS endpoint configured without ssl=True; firewall/Docker networking blocking the host; the `db` field missing so even get_redis_connection's ValueError lands here.

Related errors


AI-assisted analysis of HumanSignal/label-studio@0b49e9b539 (2026-08-29). Data as JSON: /api/errors/f48747b4badcc2fa. Report an issue: GitHub.