goharbor/harbor · critical
no worker worker is configured
Error message
no worker worker is configured
What it means
Jobservice config load fails with 'no worker worker is configured' (a known duplicated-word typo in the message) when the loaded configuration has no worker_pool section, so PoolConfig is nil. It is raised by config validation at startup and prevents jobservice from starting at all.
Source
Thrown at src/jobservice/config/config.go:333
if !utils.IsValidPort(c.Port) {
return fmt.Errorf("port number should be a none zero integer and less or equal 65535, but current is %d", c.Port)
}
if c.Protocol == JobServiceProtocolHTTPS {
if c.HTTPSConfig == nil {
return fmt.Errorf("certificate must be configured if serve with protocol %s", c.Protocol)
}
if utils.IsEmptyStr(c.HTTPSConfig.Cert) ||
!utils.FileExists(c.HTTPSConfig.Cert) ||
utils.IsEmptyStr(c.HTTPSConfig.Key) ||
!utils.FileExists(c.HTTPSConfig.Key) {
return fmt.Errorf("certificate for protocol %s is not correctly configured", c.Protocol)
}
}
if c.PoolConfig == nil {
return errors.New("no worker worker is configured")
}
if c.PoolConfig.Backend != JobServicePoolBackendRedis {
return fmt.Errorf("worker worker backend %s does not support", c.PoolConfig.Backend)
}
// When backend is redis
if c.PoolConfig.Backend == JobServicePoolBackendRedis {
if c.PoolConfig.RedisPoolCfg == nil {
return fmt.Errorf("redis worker must be configured when backend is set to '%s'", c.PoolConfig.Backend)
}
if utils.IsEmptyStr(c.PoolConfig.RedisPoolCfg.RedisURL) {
return errors.New("URL of redis worker is empty")
}
if !strings.Contains(c.PoolConfig.RedisPoolCfg.RedisURL, "://") {
return errors.New("invalid redis URL")
}
View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Add a worker_pool section with backend: redis plus a redis_pool block (the only supported backend)
- Validate YAML indentation against the jobservice config template in the repo
- Start from the shipped default config and edit it rather than writing from scratch
Example fix
# before
protocol: http
http_config:
port: 8080
# after
protocol: http
http_config:
port: 8080
worker_pool:
backend: redis
redis_pool:
redis_url: redis://:password@redis:6379/5
namespace: harbor_jobservice
worker_count: 10 Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight the config before handing it to jobservice
var cfg Config
_ = yaml.Unmarshal(raw, &cfg)
if cfg.PoolConfig == nil {
return errors.New("config.yml missing worker_pool section")
}
if cfg.PoolConfig.Backend != "redis" {
return errors.New("worker_pool.backend must be redis")
} Type guard
func isNoWorkerConfigured(err error) bool { return err != nil && strings.Contains(err.Error(), "no worker worker is configured") } Try / catch
if err := cfg.Load(...); err != nil {
if strings.Contains(err.Error(), "no worker worker is configured") {
return errors.New("add worker_pool { backend: redis, redis_pool: {...} } to config.yml")
}
return err
} Prevention
- Validate config.yml in CI with the jobservice config schema
- Diff against the shipped template after every upgrade
- Lint YAML indentation (worker_pool must be top-level)
When it happens
Trigger: Launching jobservice with a config.yml whose worker_pool block is missing or mis-indented so it never lands under the top-level key (PoolConfig parses as nil).
Common situations: Hand-written minimal configs; template drift after upgrading to a config layout that requires worker_pool; YAML indentation placing worker_pool under another key.
Related errors
- URL of redis worker is empty
- invalid redis URL
- namespace of redis worker is required
- missing logger config of job service
- missing logger config of job
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/2dc0a14124b054e4.
Report an issue: GitHub.