hcengineering/platform · error
One of endpoint/accessKey/secretKey values are not specified
Error message
One of endpoint/accessKey/secretKey values are not specified
What it means
createStorageFromConfig validates MinIO configs before constructing MinioService: endpoint, accessKey and secretKey must all be present. If any is null/undefined it throws 'One of endpoint/accessKey/secretKey values are not specified'. Since endpoint/port come from the URI and accessKey/secretKey come from query parameters of the STORAGE_CONFIG entry, this means the minio entry is incomplete.
Source
Thrown at foundations/server/packages/server-storage/src/starter.ts:86
uri.searchParams.forEach((v, k) => {
;(config as any)[k] = v
})
if (storageConfig.storages.find((it) => it.name === config.name) !== undefined) {
throw new Error(`Duplicated storage name ${config.name}, skipping config:${st}`)
}
storageConfig.storages.push(config)
storageConfig.default = config.name
}
}
export function createStorageFromConfig (config: StorageConfig): StorageAdapter {
let adapter: StorageAdapter
const kind = config.kind
if (kind === MINIO_CONFIG_KIND) {
const c = config as MinioConfig
if (c.endpoint == null || c.accessKey == null || c.secretKey == null) {
throw new Error('One of endpoint/accessKey/secretKey values are not specified')
}
adapter = new MinioService(c)
} else if (kind === S3_CONFIG_KIND) {
const c = config as S3Config
if (c.endpoint == null || c.accessKey == null || c.secretKey == null) {
throw new Error('One of endpoint/accessKey/secretKey values are not specified')
}
adapter = new S3Service(c)
} else if (kind === DATALAKE_CONFIG_KIND) {
const c = config as DatalakeConfig
if (c.endpoint == null) {
throw new Error('Endpoint value is not specified')
}
adapter = new DatalakeService(c)
} else if (kind === HULYLAKE_CONFIG_KIND) {
const c = config as HulylakeConfig
if (c.endpoint == null) {
throw new Error('Endpoint value is not specified')View on GitHub (pinned to 63e28dc964)
Solutions
- Check the minio entry of STORAGE_CONFIG includes endpoint host, accessKey and secretKey query parameters
- Verify the source environment variables (e.g. MINIO_ACCESS_KEY/SECRET_KEY) are actually set where the server runs — an unset var interpolates to an empty string
- Fix param-name casing to exactly accessKey and secretKey
- For local dev, use the fallback path: leave STORAGE_CONFIG unset so storageConfigFromEnv adds addMinioFallback with minio/minio defaults
Example fix
// before
STORAGE_CONFIG=minio|minio:9000?accessKey=${MINIO_ACCESS_KEY}&secretKey=${MINIO_SECRET_KEY}
// (MINIO_SECRET_KEY unset -> empty)
// after: ensure vars are exported
export MINIO_SECRET_KEY=miniosecret Defensive patterns
Strategy: validation
Validate before calling
function validateMinioConfig (c: Partial<MinioConfig>): void {
const missing = (['endpoint', 'accessKey', 'secretKey'] as const).filter(k => c[k] == null)
if (missing.length > 0) {
throw new Error(`minio storage config missing: ${missing.join(', ')}`)
}
}
validateMinioConfig(minioEntry) Type guard
function isMinioConfigReady (c: Partial<MinioConfig>): c is MinioConfig {
return c.endpoint != null && c.accessKey != null && c.secretKey != null
} Try / catch
try {
const adapter = createStorageFromConfig(cfg)
} catch (err) {
if ((err as Error).message.includes('endpoint/accessKey/secretKey')) {
console.error('Incomplete minio config in STORAGE_CONFIG:', cfg.name)
process.exit(1)
}
throw err
} Prevention
- Verify credential env vars are exported in the actual runtime container
- Use docker/k8s secret injection rather than shell interpolation where possible
- Smoke-test storage init at startup before accepting traffic
- Keep param names exactly accessKey/secretKey in STORAGE_CONFIG URIs
When it happens
Trigger: A minio STORAGE_CONFIG entry lacking &accessKey= or &secretKey= query params, or an empty endpoint (malformed URI part) — hit at startup via storageAdapter/buildStorageFromConfig when kind === 'minio'.
Common situations: Env var interpolation leaving ${ACCESS_KEY} empty in the composed STORAGE_CONFIG; secrets not mounted/injected in k8s so query params end up undefined; typo in param names (accesskey/secretkey case sensitivity); Docker compose variable not exported so it expands to nothing.
Related errors
- Payment provider is not configured. Please provide payment p
- Missing config for attributes: ${missingEnv.join(', ')}
- Missing config for attributes: ${missingEnv.join(', ')}
- Missing config for attributes: ${missingEnv.join(', ')}
- Missing env variables: ${missingEnv.join(', ')}
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/fd3c92830c43d95e.
Report an issue: GitHub.