JuliusBrussee/caveman · critical
objectstore: production requires TLS
Error message
objectstore: production requires TLS
What it means
validateConfig enforces TLS in production: if production is true and either UseSSL is false or the endpoint uses an http:// scheme, configuration is rejected. This prevents object data from transiting the network unencrypted in production deployments.
Solutions
- Set S3_USE_SSL=true (or Config.UseSSL=true) and ensure the endpoint is an https:// URL or a bare host that will be dialed over TLS.
- Serve the MinIO/S3 endpoint with a valid TLS certificate behind a proxy if it currently only speaks plaintext.
- Do not work around this by faking the environment flag to non-production; fix TLS instead.
- Verify certificate trust on the client side so TLS actually succeeds after enabling it.
Example fix
// before S3_ENDPOINT=http://minio.internal:9000 S3_USE_SSL=false // after S3_ENDPOINT=https://minio.internal.example.com:9000 S3_USE_SSL=true
Defensive patterns
Strategy: validation
Validate before calling
if production && (!cfg.UseSSL || strings.HasPrefix(strings.ToLower(cfg.Endpoint), "http://")) {
return errors.New("production object store must use TLS")
} Try / catch
store, err := objectstore.New(cfg)
if err != nil {
return fmt.Errorf("object store TLS config: %w", err)
} Prevention
- Always set S3_USE_SSL=true in production deploys
- Use https:// endpoint URLs so TLS is inferred correctly
- Fix certificate trust issues rather than disabling SSL
- Keep local plaintext MinIO configs out of production templates
When it happens
Trigger: Production run with S3_USE_SSL=false or unset-but-false while S3_ENDPOINT is set; endpoint explicitly given as http://... in production; config built programmatically with UseSSL:false and production=true; TLS inferred from the endpoint scheme fails because a plain host with no scheme defaults per configuration.
Common situations: Copy-pasting a local plaintext MinIO config (http://minio:9000) into a production deploy; disabling SSL to work around a certificate issue instead of fixing trust; forgetting S3_USE_SSL=true when the endpoint has no scheme.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- cave_gateway_identity_unverified
- objectstore: production endpoint must be an HTTPS origin…
- postgres: or is required in production
- objectstore: access key and secret key are required
- objectstore: endpoint and bucket are required
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/0ee45102e7bb835c.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/objectstore/objectstore.go:199
if err := Probe(ctx, store); err != nil {
return nil, fmt.Errorf("objectstore: production read/write/delete probe failed: %w", err)
}
}
return store, nil
}
func validateConfig(cfg Config, production bool) error {
if strings.TrimSpace(cfg.Endpoint) == "" || strings.TrimSpace(cfg.Bucket) == "" {
return errors.New("objectstore: endpoint and bucket are required")
}
if strings.TrimSpace(cfg.AccessKey) == "" || strings.TrimSpace(cfg.SecretKey) == "" {
return errors.New("objectstore: access key and secret key are required")
}
if !production {
return nil
}
if !cfg.UseSSL || strings.HasPrefix(strings.ToLower(strings.TrimSpace(cfg.Endpoint)), "http://") {
return errors.New("objectstore: production requires TLS")
}
raw := strings.TrimSpace(cfg.Endpoint)
if !strings.Contains(raw, "://") {
raw = "https://" + raw
}
u, err := url.Parse(raw)
if err != nil || u.Scheme != "https" || u.Hostname() == "" || u.User != nil || u.RawQuery != "" || u.Fragment != "" || (u.Path != "" && u.Path != "/") {
return errors.New("objectstore: production endpoint must be an HTTPS origin without credentials, path, query, or fragment")
}
return nil
}
// New constructs a MinIO/S3-backed Store. FromEnv adds a live production probe.
func New(cfg Config) (Store, error) {
endpoint := strings.TrimPrefix(strings.TrimPrefix(cfg.Endpoint, "https://"), "http://")
client, err := minio.New(endpoint, &minio.Options{
Creds: credentials.NewStaticV4(cfg.AccessKey, cfg.SecretKey, ""),
Secure: cfg.UseSSL,View on GitHub (pinned to 3ee70a1026)