coollabsio/coolify · error · RuntimeException
Invalid dockerfile_target_build: contains forbidden characte
Error message
Invalid dockerfile_target_build: contains forbidden characters.
What it means
During deployment, ApplicationDeploymentJob interpolates application->dockerfile_target_build into the docker build --target argument. Before doing so it validates the value against ValidationPatterns::DOCKER_TARGET_PATTERN (/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/): it must start alphanumeric and contain only letters, digits, dots, hyphens, underscores. Anything else — leading . or -, spaces, $, quotes, unicode — throws, protecting the shell command from injection.
Source
Thrown at app/Jobs/ApplicationDeploymentJob.php:353
if (preg_match('/-(\d{12})/', $containerName)) {
continue;
}
$containerIp = data_get($container, 'IPv4Address');
if ($containerName && $containerIp) {
$containerIp = str($containerIp)->before('/');
$ips->put($containerName, $containerIp->value());
}
}
}
$this->addHosts = $ips->map(function ($ip, $name) {
return "--add-host $name:$ip";
})->implode(' ');
}
if ($this->application->dockerfile_target_build) {
$target = $this->application->dockerfile_target_build;
if (! preg_match(ValidationPatterns::DOCKER_TARGET_PATTERN, $target)) {
throw new \RuntimeException('Invalid dockerfile_target_build: contains forbidden characters.');
}
$this->buildTarget = " --target {$target} ";
}
// Check custom port
['repository' => $this->customRepository, 'port' => $this->customPort] = $this->application->customRepository();
if (data_get($this->application, 'settings.is_build_server_enabled')) {
$teamId = data_get($this->application, 'environment.project.team.id');
$buildServers = Server::buildServers($teamId)->get();
if ($buildServers->count() === 0) {
$this->application_deployment_queue->addLogEntry('No suitable build server found. Using the deployment server.');
$this->build_server = $this->server;
} else {
$this->build_server = $buildServers->random();
$this->application_deployment_queue->build_server_id = $this->build_server->id;
$this->application_deployment_queue->addLogEntry("Found a suitable build server ({$this->build_server->name}).");
$this->use_build_server = true;View on GitHub (pinned to 70b9acc424)
Solutions
- Set the Build Target field to a plain stage name that starts with a letter or digit, e.g. 'builder' or 'production' (letters, digits, . _ - only after the first char).
- Rename the corresponding stage in your Dockerfile to match the allowed pattern.
- Clear the field entirely if you do not need multi-stage targeting.
- If storing via API, apply ValidationPatterns::dockerTargetRules() on save so it fails at input time, not deploy time.
Example fix
# before: invalid build target stored on the application # Dockerfile stage: FROM node:20 AS builder prod dockerfile_target_build: 'builder prod' # after: rename the stage and use it verbatim # Dockerfile: FROM node:20 AS builder-prod dockerfile_target_build: 'builder-prod'
Defensive patterns
Strategy: validation
Validate before calling
// Validate on save (UI/API), not at deploy time
$validated = $request->validate([
'dockerfile_target_build' => ValidationPatterns::dockerTargetRules(), // nullable|string|max:128|regex:/^[a-zA-Z0-9][a-zA-Z0-9._-]*$/
]); Type guard
function isValidBuildTarget(?string $target): bool
{
return blank($target) || preg_match(\App\Support\ValidationPatterns::DOCKER_TARGET_PATTERN, $target) === 1;
} Prevention
- Apply the same DOCKER_TARGET_PATTERN regex rule where the field is stored, not only in the deployment job.
- Offer a dropdown of stage names parsed from the Dockerfile instead of free text.
- On redeploy failures, check legacy records: applications whose stored target predates the validation.
When it happens
Trigger: Deploying an application whose 'Build Target' (dockerfile_target_build) field holds e.g. '.prod', '-builder', 'builder stage', 'prod$(whoami)', or any value copied with a space/quote; the field was set via UI or API without passing the same regex rule.
Common situations: Copy-pasting a stage name with whitespace; using shell-style variable names like $TARGET; older records saved before this validation existed now failing on redeploy.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid {$fieldName}: contains forbidden shell characters.
- Invalid {$fieldName}: contains forbidden characters.
- Invalid {$fieldName}: path traversal detected.
- Invalid container name: contains forbidden characters.
- Pre-deployment command: Could not find a valid container. Is
AI-assisted analysis of coollabsio/coolify@70b9acc424 (2026-08-17).
Data as JSON: /api/errors/ae2670e041371793.
Report an issue: GitHub.