{"record":{"id":"9cbdbcf5a5b4757d","repo":"Tencent/WeKnora","slug":"failed-to-initialize-minio-client-w","errorCode":null,"errorMessage":"failed to initialize MinIO client: %w","messagePattern":"failed to initialize MinIO client: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/file/minio.go","lineNumber":43,"sourceCode":"}\n\n// newMinioClient creates a bare minioFileService with just the SDK client initialised.\n// Shared by NewMinioFileService (which also ensures the bucket exists) and\n// CheckMinioConnectivity (read-only probe).\nfunc newMinioClient(endpoint, accessKeyID, secretAccessKey, bucketName string, useSSL bool) (*minioFileService, error) {\n\tif err := utils.ValidateURLForSSRF(endpoint); err != nil {\n\t\treturn nil, fmt.Errorf(\"unsafe MinIO endpoint: %w\", err)\n\t}\n\thttpConfig := utils.DefaultSSRFSafeHTTPClientConfig()\n\tclient, err := minio.New(endpoint, &minio.Options{\n\t\tCreds:  credentials.NewStaticV4(accessKeyID, secretAccessKey, \"\"),\n\t\tSecure: useSSL,\n\t\tTransport: &utils.SSRFValidatingRoundTripper{\n\t\t\tBase: utils.NewSSRFSafeTransport(httpConfig),\n\t\t},\n\t})\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to initialize MinIO client: %w\", err)\n\t}\n\treturn &minioFileService{client: client, bucketName: bucketName}, nil\n}\n\n// NewMinioFileService creates a MinIO file service.\n// It verifies that the bucket exists and creates it if missing.\nfunc NewMinioFileService(endpoint,\n\taccessKeyID, secretAccessKey, bucketName string, useSSL bool,\n) (interfaces.FileService, error) {\n\tsvc, err := newMinioClient(endpoint, accessKeyID, secretAccessKey, bucketName, useSSL)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\texists, err := svc.client.BucketExists(context.Background(), bucketName)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to check bucket: %w\", err)\n\t}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/file/minio.go#L25-L61","documentation":"newMinioClient wraps an error returned by minio.New (minio-go/v7 SDK client construction) as \"failed to initialize MinIO client: %w\". minio.New only fails when it cannot build a valid client from the inputs — most commonly an empty endpoint — since credentials are supplied as a static provider and no network I/O happens here.","triggerScenarios":"minio.New(endpoint, &minio.Options{...}) returns an error, which in minio-go/v7 happens when the endpoint string is empty or cannot be parsed into a valid host:port pair (e.g. MINIO_ENDPOINT unset, contains only a scheme, or has illegal characters).","commonSituations":"MINIO_ENDPOINT environment variable not set in the deployment; trailing slash or embedded path in the endpoint value; endpoint copied with \"http://\" plus a path like /minio that the SDK cannot parse; whitespace or quotes accidentally included in the env value.","solutions":["Ensure MINIO_ENDPOINT is a non-empty host (optionally host:port) with no scheme or path, e.g. minio.example.com:9000, and restart the service","Print the wrapped error (errors.Unwrap / %v) to see minio-go's exact parse message and correct the value","Strip quotes/whitespace from the env value in your shell/compose file (use MINIO_ENDPOINT=minio:9000 without surrounding quotes inside YAML values where they become literal)","Note that empty access/secret keys do NOT fail here (static credentials are accepted); if credentials are the concern, the failure will surface later at BucketExists, not at client init"],"exampleFix":"// before\nMINIO_ENDPOINT=\"http://minio:9000/\"  // scheme+path confuse minio.New\n// after\nMINIO_ENDPOINT=minio:9000  # host[:port] only; scheme controlled by useSSL flag","handlingStrategy":"validation","validationCode":"func validateEndpointFormat(endpoint string) error {\n    if strings.TrimSpace(endpoint) == \"\" {\n        return fmt.Errorf(\"MINIO_ENDPOINT is empty\")\n    }\n    if strings.HasPrefix(endpoint, \"http://\") || strings.HasPrefix(endpoint, \"https://\") || strings.Contains(endpoint, \"/\") {\n        return fmt.Errorf(\"endpoint must be host[:port] only, no scheme or path: %q\", endpoint)\n    }\n    host, port, err := net.SplitHostPort(endpoint)\n    if err != nil {\n        host = endpoint // port optional\n    } else if _, err := strconv.Atoi(port); err != nil {\n        return fmt.Errorf(\"invalid port %q\", port)\n    }\n    if host == \"\" {\n        return fmt.Errorf(\"endpoint missing host: %q\", endpoint)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"svc, err := file.NewMinioFileService(endpoint, ak, sk, bucket, useSSL)\nif err != nil && strings.Contains(err.Error(), \"failed to initialize MinIO client\") {\n    return fmt.Errorf(\"bad MINIO_ENDPOINT %q (want host[:port]): %w\", endpoint, err)\n} else if err != nil {\n    return err\n}","preventionTips":["Store MINIO_ENDPOINT as host[:port] without scheme, path, quotes, or trailing slash","Fail fast with a config validation step at service startup","Read env vars with trimming (strings.TrimSpace) to catch stray whitespace","Document the expected format next to the env var in your deployment templates"],"tags":["minio","configuration","sdk-initialization","env-var"],"backgroundTag":"invalid-endpoint-config","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}