docker/compose · error
project name can't be empty. Use ProjectName option to set a
Error message
project name can't be empty. Use ProjectName option to set a valid name
What it means
After loading a project, postProcessProject asserts that a project name was resolved (from the `name:` field in the compose file, --project-name, COMPOSE_PROJECT_NAME, or the sanitized directory name). An empty name means labels and resource scoping would be broken, so Compose refuses to continue.
Source
Thrown at pkg/compose/loader.go:122
// get compose file path set by COMPOSE_FILE
cli.WithConfigFileEnv,
// if none was selected, get default compose.yaml file from current dir or parent folder
cli.WithDefaultConfigPath,
// .. and then, a project directory != PWD maybe has been set so let's load .env file
cli.WithEnvFiles(options.EnvFiles...), //nolint:gocritic // intentionally applying cli.WithEnvFiles twice.
cli.WithDotEnv, //nolint:gocritic // intentionally applying cli.WithDotEnv twice.
// eventually COMPOSE_PROFILES should have been set
cli.WithDefaultProfiles(options.Profiles...),
cli.WithName(options.ProjectName),
)
return cli.NewProjectOptions(options.ConfigPaths, append(options.ProjectOptionsFns, opts...)...)
}
// postProcessProject applies post-loading transformations to the project
func (s *composeService) postProcessProject(project *types.Project, options api.ProjectLoadOptions) (*types.Project, error) {
if project.Name == "" {
return nil, errors.New("project name can't be empty. Use ProjectName option to set a valid name")
}
project, err := project.WithServicesEnabled(options.Services...)
if err != nil {
return nil, err
}
// Add custom labels
for name, s := range project.Services {
s.CustomLabels = map[string]string{
api.ProjectLabel: project.Name,
api.ServiceLabel: name,
api.VersionLabel: api.ComposeVersion,
api.WorkingDirLabel: project.WorkingDir,
api.ConfigFilesLabel: strings.Join(project.ComposeFiles, ","),
api.OneoffLabel: "False",
}
if len(options.EnvFiles) != 0 {View on GitHub (pinned to ddc4b044b6)
Solutions
- Add `name: myproject` to the top of your compose file
- Pass `--project-name myproject` on the command line
- Export COMPOSE_PROJECT_NAME=myproject in the environment
- API users: set ProjectName in api.ProjectLoadOptions before calling the load API
Example fix
# before
services:
web:
image: nginx
# after
name: myproject
services:
web:
image: nginx Defensive patterns
Strategy: validation
Validate before calling
# Go API: always set the project name explicitly before loading
opts := api.ProjectLoadOptions{
ProjectName: "myproject", // or load from env
}
// CLI: ensure one name source exists
[ -n "$COMPOSE_PROJECT_NAME" ] || grep -q '^name:' compose.yaml || echo 'set a project name' Prevention
- Always put `name:` at the top of compose.yaml in repos
- When loading config from stdin with the API, pass ProjectName explicitly since directory derivation may not apply
When it happens
Trigger: cli.NewProjectOptions runs without any name source: no name: in the file, no ProjectName option, no COMPOSE_PROJECT_NAME, and no derivable directory name (e.g. reading config from stdin '-' with an empty/odd directory, or a directory name that sanitizes to empty such as '123' or non-alpha characters).
Common situations: Using the Go API with ProjectLoadOptions but forgetting ProjectName and loading from a reader; CI running compose with config piped via stdin; a project directory whose name starts with digits or contains only invalid chars after sanitization; COMPOSE_PROJECT_NAME set to empty string explicitly.
Related errors
- source can not be empty
- destination can not be empty
- invalid filter '${filter}'
- --index requires one service to be selected
- arguments to --filter should be in form KEY=VAL
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/2896c3033c3408b4.
Report an issue: GitHub.