hibiken/asynq · error

asynq: could not parse redis uri

Error message

asynq: could not parse redis uri: %w

What it means

Returned by ParseRedisURI when the URI string does not match any of the supported redis/rediss/redis-socket/redis-sentinel formats (bad scheme, malformed host/port, or unparseable components). The wrapped error %w carries the underlying parse failure; the URI is rejected before any Redis connection option is produced.

Solutions

  1. Fix the URI syntax; the wrapped error from net/url points at the exact problem
  2. URL-escape credentials with url.UserPassword or net/url escaping before composing the URI
  3. Trim quotes/whitespace from environment variables before passing the value

Example fix

// before
opt, err := asynq.ParseRedisURI("redis://user:p@ss@localhost:6379")
// after
opt, err := asynq.ParseRedisURI("redis://user:p%40ss@localhost:6379")
Defensive patterns

Strategy: validation

Validate before calling

func validateRedisURI(uri string) error {
    if _, err := url.Parse(uri); err != nil {
        return fmt.Errorf("invalid redis uri: %w", err)
    }
    return nil
}

Try / catch

opt, err := asynq.ParseRedisURI(uri)
if err != nil {
    var urlErr *url.Error
    if errors.As(err, &urlErr) {
        return fmt.Errorf("bad redis URI %q: %v", uri, urlErr.Err)
    }
    return err
}

Prevention

When it happens

Trigger: Passing a syntactically invalid URI (e.g. missing scheme, stray characters, invalid percent-encoding) to ParseRedisURI or via a redis:// URI when configuring the server with Config{Redis: parsedOpt}.

Common situations: Environment-variable-provided Redis URLs with unescaped special characters in the password (@, :, /); copy-pasted URIs with quotes or whitespace; building the URI by string concatenation without escaping.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07). Data as JSON: /api/errors/798414fc55ec0a46. Report an issue: GitHub.

Appendix: source

Thrown at asynq.go:479

		WriteTimeout: opt.WriteTimeout,
		TLSConfig:    opt.TLSConfig,
	})
}

// ParseRedisURI parses redis uri string and returns RedisConnOpt if uri is valid.
// It returns a non-nil error if uri cannot be parsed.
//
// Three URI schemes are supported, which are redis:, rediss:, redis-socket:, and redis-sentinel:.
// Supported formats are:
//
//	redis://[:password@]host[:port][/dbnumber]
//	rediss://[:password@]host[:port][/dbnumber]
//	redis-socket://[:password@]path[?db=dbnumber]
//	redis-sentinel://[:password@]host1[:port][,host2:[:port]][,hostN:[:port]][/dbnumber][?master=masterName]
func ParseRedisURI(uri string) (RedisConnOpt, error) {
	u, err := url.Parse(uri)
	if err != nil {
		return nil, fmt.Errorf("asynq: could not parse redis uri: %w", err)
	}
	switch u.Scheme {
	case "redis", "rediss":
		return parseRedisURI(u)
	case "redis-socket":
		return parseRedisSocketURI(u)
	case "redis-sentinel":
		return parseRedisSentinelURI(u)
	default:
		return nil, fmt.Errorf("asynq: unsupported uri scheme: %q", u.Scheme)
	}
}

func parseRedisURI(u *url.URL) (RedisConnOpt, error) {
	var db int
	var err error
	var redisConnOpt RedisClientOpt

View on GitHub (pinned to d135f1439b)