{"record":{"id":"38f85a22c0459674","repo":"JuliusBrussee/caveman","slug":"objectstore-access-key-and-secret-key-are-require","errorCode":null,"errorMessage":"objectstore: access key and secret key are required","messagePattern":"objectstore: access key and secret key are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"shared/platform/objectstore/objectstore.go","lineNumber":193,"sourceCode":"\t\ttimeout := time.Duration(env.Int(\"CAVE_OBJECTSTORE_PROBE_TIMEOUT_MS\", 10000)) * time.Millisecond\n\t\tif timeout <= 0 {\n\t\t\ttimeout = 10 * time.Second\n\t\t}\n\t\tctx, cancel := context.WithTimeout(context.Background(), timeout)\n\t\tdefer cancel()\n\t\tif err := Probe(ctx, store); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"objectstore: production read/write/delete probe failed: %w\", err)\n\t\t}\n\t}\n\treturn store, nil\n}\n\nfunc validateConfig(cfg Config, production bool) error {\n\tif strings.TrimSpace(cfg.Endpoint) == \"\" || strings.TrimSpace(cfg.Bucket) == \"\" {\n\t\treturn errors.New(\"objectstore: endpoint and bucket are required\")\n\t}\n\tif strings.TrimSpace(cfg.AccessKey) == \"\" || strings.TrimSpace(cfg.SecretKey) == \"\" {\n\t\treturn errors.New(\"objectstore: access key and secret key are required\")\n\t}\n\tif !production {\n\t\treturn nil\n\t}\n\tif !cfg.UseSSL || strings.HasPrefix(strings.ToLower(strings.TrimSpace(cfg.Endpoint)), \"http://\") {\n\t\treturn errors.New(\"objectstore: production requires TLS\")\n\t}\n\traw := strings.TrimSpace(cfg.Endpoint)\n\tif !strings.Contains(raw, \"://\") {\n\t\traw = \"https://\" + raw\n\t}\n\tu, err := url.Parse(raw)\n\tif err != nil || u.Scheme != \"https\" || u.Hostname() == \"\" || u.User != nil || u.RawQuery != \"\" || u.Fragment != \"\" || (u.Path != \"\" && u.Path != \"/\") {\n\t\treturn errors.New(\"objectstore: production endpoint must be an HTTPS origin without credentials, path, query, or fragment\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":175,"sourceCodeEnd":211,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/3ee70a102609e550bd2e68004bf5990a9341c851/shared/platform/objectstore/objectstore.go#L175-L211","documentation":"validateConfig requires non-empty AccessKey and SecretKey credentials for the S3 backend. Without them the MinIO client cannot authenticate, so configuration fails fast with this error before any connection attempt.","triggerScenarios":"Calling New/FromEnv with empty AccessKey or SecretKey (env vars S3_ACCESS_KEY / S3_SECRET_ACCESS_KEY or AWS-conventional S3_ACCESS_KEY_ID / S3_SECRET_ACCESS_KEY unset); whitespace-only credential values (TrimSpace'd); a secret manager that injected empty strings.","commonSituations":"Deploying with the endpoint/bucket set but the credential secret not mounted; rotating credentials and leaving an env var empty; using AWS-style variable names without knowing both naming conventions are accepted.","solutions":["Set both S3_ACCESS_KEY (or S3_ACCESS_KEY_ID) and S3_SECRET_ACCESS_KEY in the environment or Config fields.","Verify the secret volume/env mapping actually reaches the process (kubectl exec env / docker inspect).","Check for empty-string values after credential rotation or templating — whitespace-only also fails.","If credentials are legitimately not needed (anonymous bucket), this store still requires them; supply machine credentials."],"exampleFix":"// before\n# S3_ACCESS_KEY unset\n// after\nexport S3_ACCESS_KEY_ID=\"caveman-svc\"\nexport S3_SECRET_ACCESS_KEY=\"$SECRET_VALUE\"","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(cfg.AccessKey) == \"\" || strings.TrimSpace(cfg.SecretKey) == \"\" {\n    return errors.New(\"S3 credentials must be set\")\n}","typeGuard":null,"tryCatchPattern":"store, err := objectstore.New(cfg)\nif err != nil {\n    return fmt.Errorf(\"object store credentials: %w\", err)\n}","preventionTips":["Mount credential secrets explicitly and verify with an env dump in the container","Remember both S3_ACCESS_KEY/S3_SECRET_ACCESS_KEY and AWS-style S3_ACCESS_KEY_ID names are accepted","Handle empty-string injection from templated secrets after rotation"],"tags":["objectstore","configuration","credentials"],"backgroundTag":"missing-credentials","analyzedSha":"3ee70a102609e550bd2e68004bf5990a9341c851","analyzedAt":"2026-09-20T15:53:39.229Z","contentChangedAt":"2026-09-20T15:53:39.229Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}