{"record":{"id":"c918cebc0b8908c1","repo":"goharbor/harbor","slug":"invalid-redis-url","errorCode":null,"errorMessage":"invalid redis URL","messagePattern":"invalid redis URL","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"src/jobservice/config/config.go","lineNumber":349,"sourceCode":"\n\tif c.PoolConfig == nil {\n\t\treturn errors.New(\"no worker worker is configured\")\n\t}\n\n\tif c.PoolConfig.Backend != JobServicePoolBackendRedis {\n\t\treturn fmt.Errorf(\"worker worker backend %s does not support\", c.PoolConfig.Backend)\n\t}\n\n\t// When backend is redis\n\tif c.PoolConfig.Backend == JobServicePoolBackendRedis {\n\t\tif c.PoolConfig.RedisPoolCfg == nil {\n\t\t\treturn fmt.Errorf(\"redis worker must be configured when backend is set to '%s'\", c.PoolConfig.Backend)\n\t\t}\n\t\tif utils.IsEmptyStr(c.PoolConfig.RedisPoolCfg.RedisURL) {\n\t\t\treturn errors.New(\"URL of redis worker is empty\")\n\t\t}\n\t\tif !strings.Contains(c.PoolConfig.RedisPoolCfg.RedisURL, \"://\") {\n\t\t\treturn errors.New(\"invalid redis URL\")\n\t\t}\n\n\t\tif _, err := url.Parse(c.PoolConfig.RedisPoolCfg.RedisURL); err != nil {\n\t\t\treturn fmt.Errorf(\"invalid redis URL: %s\", err.Error())\n\t\t}\n\n\t\tif utils.IsEmptyStr(c.PoolConfig.RedisPoolCfg.Namespace) {\n\t\t\treturn errors.New(\"namespace of redis worker is required\")\n\t\t}\n\t}\n\n\t// Job service loggers\n\tif len(c.LoggerConfigs) == 0 {\n\t\treturn errors.New(\"missing logger config of job service\")\n\t}\n\n\t// Job loggers\n\tif len(c.JobLoggerConfigs) == 0 {","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/jobservice/config/config.go#L331-L367","documentation":"Harbor job service configuration error thrown from Config.validate() (src/jobservice/config/config.go:349) when the worker pool backend is 'redis' but RedisPoolCfg.RedisURL contains no '://' scheme separator. The service refuses to start because the Redis pool needs a full URL to dial. Note that the normal YAML/env load path auto-prepends 'redis://' to scheme-less addresses (config.go:172-183), so this variant mainly fires when a Config struct is built programmatically and validated directly, or when the later url.Parse fails (that sibling case reports 'invalid redis URL: %s').","triggerScenarios":"Calling Load/Validate on a Config with PoolConfig.Backend == JobServicePoolBackendRedis and RedisPoolCfg.RedisURL like 'redis:6379' or 'myredis:6379' (no scheme); constructing the config by hand in tests or embedded jobservice use instead of going through the YAML loader; env JOB_SERVICE_POOL_REDIS_URL set to a scheme-less host:port in a code path that skips the translate step.","commonSituations":"Older docs/examples showing host:port form; Helm values injecting a scheme-less URL into a custom image; unit tests constructing Config directly; copy-paste of 'redis:6379' from docker-compose service names.","solutions":["Write the URL with an explicit scheme: redis://:password@host:6379/0 (rediss:// for TLS)","Prefer loading config through config.Load from YAML/env — it prepends redis:// to scheme-less addresses before validating","Check the effective value of JOB_SERVICE_POOL_REDIS_URL / jobservice.pool.redis_url inside the jobservice container","If Redis was not intended, set the pool backend to 'database' and drop the Redis pool config"],"exampleFix":"// before\ncfg.PoolConfig.RedisPoolCfg.RedisURL = \"redis:6379\"\n// after\ncfg.PoolConfig.RedisPoolCfg.RedisURL = \"redis://:password@redis:6379/0\"","handlingStrategy":"validation","validationCode":"func checkRedisURL(raw string) error {\n    if !strings.Contains(raw, \"://\") {\n        return fmt.Errorf(\"redis URL %q must include a scheme (redis:// or rediss://)\", raw)\n    }\n    if _, err := url.Parse(raw); err != nil {\n        return fmt.Errorf(\"redis URL does not parse: %w\", err)\n    }\n    return nil\n}","typeGuard":"func isSchemedRedisURL(raw string) bool {\n    return strings.Contains(raw, \"://\")\n}","tryCatchPattern":null,"preventionTips":["Load config through config.Load (YAML/env) so scheme-less Redis addresses are auto-prefixed with redis://","Add a CI step that runs Config.Validate() on the rendered config before deploying","Standardize on redis://…/rediss:// forms in every environment"],"tags":["redis","configuration","jobservice","harbor","url","startup"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}