Crosstalk-Solutions/project-nomad · error
guard.blocked.join(' ')
Error message
guard.blocked.join(' ') What it means
A 422 from createCustomApp when evaluateCustomApp hard-blocks the request. The guard rejects dangerous bind mounts (e.g. mounting / or /var/run/docker.sock) and malformed image references; these blocks cannot be overridden with force=true.
Source
Thrown at admin/app/controllers/system_controller.ts:400
})
}
// Reject duplicate host ports within the request — Docker would otherwise fail at
// start time with an opaque "port is already allocated" error.
const hostPorts = (payload.ports ?? []).map((p) => p.host)
const duplicateHostPorts = [...new Set(hostPorts.filter((p, i) => hostPorts.indexOf(p) !== i))]
if (duplicateHostPorts.length) {
return response.status(422).send({
success: false,
message: `Duplicate host port(s): ${duplicateHostPorts.join(', ')}. Each host port can map to only one container.`,
})
}
// Security guardrails: hard-block dangerous bind mounts / malformed images regardless of
// force; surface overridable warnings (risky paths, untrusted/moving-tag images) unless forced.
const guard = evaluateCustomApp({ image: payload.image, volumes: payload.volumes })
if (guard.blocked.length) {
return response.status(422).send({
success: false,
message: guard.blocked.join(' '),
blocked: guard.blocked,
})
}
if (!payload.force && guard.warnings.length) {
return response.status(409).send({
success: false,
message: guard.warnings.join(' '),
warnings: guard.warnings,
})
}
// Advisory preflight: surface port conflicts before creating the record so a failed
// install doesn't leave a phantom card. The user can re-submit with force=true to override.
if (!payload.force && hostPorts.length) {
const { conflicts } = await this.dockerService.checkPortConflicts(hostPorts)
if (conflicts.length) {View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Read guard.blocked in the response — each entry names the rejected volume/image and why
- Remove or narrow the dangerous bind mount (mount only a specific subdirectory)
- Fix the image reference to a valid registry/name:tag form
- Note: force=true will NOT bypass blocked items by design
Example fix
// before
volumes: [{ host: '/var/run/docker.sock', container: '/var/run/docker.sock' }]
// after
volumes: [{ host: '/opt/myapp/data', container: '/data' }] Defensive patterns
Strategy: validation
Validate before calling
const blocked = evaluateCustomApp({ image, volumes }); // if available client-side
const dangerous = volumes?.some((v) => /^\/(var\/run\/docker\.sock|etc|var)?$/.test(v.host));
if (dangerous) disableSubmit(); Type guard
const isSafeMount = (h: string) => !/^\/(var\/run\/docker\.sock|root|etc|var|bin|sbin|usr|lib)?$/g.test(h);
Prevention
- Never mount the Docker socket or host root
- Remember force cannot bypass blocked items
When it happens
Trigger: POST create-custom-app with a volume like /:/host or /var/run/docker.sock:/var/run/docker.sock, or an image string that fails reference validation.
Common situations: User tries to give an app Docker control via the socket mount, mounts the host root, or typos the image name so it doesn't parse as a valid reference.
Related errors
- guard.warnings.join(' ')
- sysbench disk-write benchmark produced no parseable MiB/s —
- Sysbench command failed: ${error.message}
- Failed to get auth token from ${registry}: ${response.status
- No token returned from ${registry}
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/969337cbab9702f8.
Report an issue: GitHub.