{"id":"d70d00c445b4fb50","repo":"go-redis/redis","slug":"redis-unexpected-option-s-d70d00","errorCode":null,"errorMessage":"redis: unexpected option: %s","messagePattern":"redis: unexpected option: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"osscluster.go","lineNumber":422,"sourceCode":"\n\tif q.err != nil {\n\t\treturn nil, q.err\n\t}\n\n\t// addr can be specified as many times as needed\n\taddrs := q.strings(\"addr\")\n\tfor _, addr := range addrs {\n\t\th, p, err := net.SplitHostPort(addr)\n\t\tif err != nil || h == \"\" || p == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"redis: unable to parse addr param: %s\", addr)\n\t\t}\n\n\t\to.Addrs = append(o.Addrs, net.JoinHostPort(h, p))\n\t}\n\n\t// any parameters left?\n\tif r := q.remaining(); len(r) > 0 {\n\t\treturn nil, fmt.Errorf(\"redis: unexpected option: %s\", strings.Join(r, \", \"))\n\t}\n\n\treturn o, nil\n}\n\nfunc (opt *ClusterOptions) clientOptions() *Options {\n\t// Clone MaintNotificationsConfig to avoid sharing between cluster node clients\n\tvar maintNotificationsConfig *maintnotifications.Config\n\tif opt.MaintNotificationsConfig != nil {\n\t\tconfigClone := *opt.MaintNotificationsConfig\n\t\tmaintNotificationsConfig = &configClone\n\t}\n\n\treturn &Options{\n\t\tClientName: opt.ClientName,\n\t\tDialer:     opt.Dialer,\n\t\tOnConnect:  opt.OnConnect,\n","sourceCodeStart":404,"sourceCodeEnd":440,"githubUrl":"https://github.com/go-redis/redis/blob/36d97525cd8076aed67cddf54778e9ea84550929/osscluster.go#L404-L440","documentation":"Returned by setupClusterQueryParams when query parameters remain after all recognised cluster options are consumed. Same strictness as the standalone path: unknown cluster URL query keys are an error, listed comma-separated.","triggerScenarios":"A cluster URL like redis://host:7000/?shards=3 (no such option) or redis://host:7000/?maxredirects=5 (correct name is max_redirects). Any unrecognised snake_case key triggers it.","commonSituations":"Typos in option names, options carried over from another driver, or parameters that only exist on the standalone Options (e.g. min_idle_conns is supported, but many arbitrary keys are not).","solutions":["Rename the leftover key to the supported snake_case name (see setupClusterQueryParams for the accepted set).","Remove the unsupported parameter.","Set the value on *redis.ClusterOptions directly if there is no URL equivalent."],"exampleFix":"// before\nopt, err := redis.ParseClusterURL(\"redis://host:7000/?maxredirects=5\")\n// after\nopt, err := redis.ParseClusterURL(\"redis://host:7000/?max_redirects=5\")","handlingStrategy":"validation","validationCode":"var knownClusterParams = map[string]bool{\n    \"addr\": true, \"protocol\": true, \"client_name\": true, \"max_redirects\": true,\n    \"read_only\": true, \"route_by_latency\": true, \"route_randomly\": true,\n    \"max_retries\": true, \"min_retry_backoff\": true, \"max_retry_backoff\": true,\n    \"dial_timeout\": true, \"dialer_retries\": true, \"dialer_retry_timeout\": true,\n    \"read_timeout\": true, \"write_timeout\": true, \"pool_fifo\": true,\n    \"pool_size\": true, \"max_concurrent_dials\": true, \"min_idle_conns\": true,\n    \"max_idle_conns\": true, \"max_active_conns\": true, \"pool_timeout\": true,\n    \"conn_max_lifetime\": true, \"conn_max_lifetime_jitter\": true,\n    \"conn_max_idle_time\": true, \"failing_timeout_seconds\": true,\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reference setupClusterQueryParams for the accepted cluster param set.","Set unsupported options on ClusterOptions directly.","Avoid copy-pasting standalone-only params into cluster URLs."],"tags":["config","url","cluster","validation"],"analyzedSha":"36d97525cd8076aed67cddf54778e9ea84550929","analyzedAt":"2026-08-06T01:08:27.376Z","schemaVersion":2}