How to fix ERROR: for web Cannot create container for service web: invalid port specification in Docker

DockerBEGINNERMEDIUMUpdated Dec 6, 2025ยท 221 views

The 'invalid port specification' error occurs when Docker Compose cannot parse your port mapping syntax. This typically happens due to unquoted port values, undefined environment variables, or malformed port formats. Fix it by quoting ports as strings and validating your syntax.

Quick fix

Fixes ERROR: for web Cannot create container for service web: invalid port specification

# WRONG: May be misinterpreted by YAML parser
services:
  web:
    ports:
      - 8080:80
      - 3000:3000
      - 8025:25    # This becomes 4825 due to base-60 parsing!

# CORRECT: Always quote port mappings
services:
  web:
    ports:
      - "8080:80"
      - "3000:3000"
      - "8025:25"
  1. Quote all port values as strings
  2. Fix environment variable port definitions
  3. Verify port format syntax
  4. Use long-form port syntax for complex cases
docker โ€” error
# WRONG: May be misinterpreted by YAML parser
services:
web:
ports:
- 8080:80
- 3000:3000
- 8025:25 # This becomes 4825 due to base-60 parsing!
# CORRECT: Always quote port mappings
services:
web:
ports:
- "8080:80"
- "3000:3000"
- "8025:25"
ERROR: for web Cannot create container for service web: invalid port specification

What this error means

The "Cannot create container for service: invalid port specification" error means Docker Compose failed to interpret your port mapping configuration in the `docker-compose.yml` file. Docker port mappings follow specific formats like `HOST:CONTAINER` (e.g., `8080:80`) or `IP:HOST:CONTAINER` (e.g., `127.0.0.1:8080:80`). When the configuration doesn't match these expected patterns, or when YAML parsing produces unexpected values, Docker rejects the specification. The most common culprit is YAML's base-60 number parsing. Without quotes, a port mapping like `80:25` is interpreted as a sexagesimal (base-60) number, resulting in `4825` instead of the intended host:container mapping. This is why Docker recommends always quoting port values as strings.

Typical symptoms

  • docker-compose up fails immediately with 'invalid port specification' error
  • Error message shows unexpected values like 'None' or strange numbers
  • Service worked with older docker-compose versions but fails after upgrade
  • Port mapping works with docker run but fails in docker-compose.yml
  • Error only appears for certain services, not all
  • Error shows 'invalid port specification: None' when using environment variables

Common causes

  1. Port values not quoted as strings in docker-compose.yml (YAML base-60 parsing issue)
  2. Environment variable for port is undefined or empty, resulting in 'None'
  3. Invalid port format: missing colon, extra colons, or typos
  4. Port number out of valid range (1-65535)
  5. Using UDP syntax incorrectly (e.g., '8080/udp:8080/udp' instead of '8080:8080/udp')
  6. ENV variable in Dockerfile has spaces around the equals sign
  7. Port range syntax error (start port greater than end port)
  8. Using network_mode: host with port mappings (incompatible configuration)

How to fix "ERROR: for web Cannot create container for service web: invalid port specification"

1Quote all port values as strings

The most common fix is to wrap port mappings in quotes. YAML parses certain numeric patterns (like xx:yy where yy < 60) as base-60 numbers:

yaml
# WRONG: May be misinterpreted by YAML parser
services:
  web:
    ports:
      - 8080:80
      - 3000:3000
      - 8025:25    # This becomes 4825 due to base-60 parsing!

# CORRECT: Always quote port mappings
services:
  web:
    ports:
      - "8080:80"
      - "3000:3000"
      - "8025:25"

This is the official Docker recommendation for avoiding YAML parsing surprises.

2Fix environment variable port definitions

If the error shows invalid port specification: 'None', an environment variable is not being set:

yaml
# Check your docker-compose.yml
services:
  web:
    ports:
      - "${WEB_PORT}:3000"  # WEB_PORT might be undefined

Solutions:

1. Create a `.env` file in the same directory as docker-compose.yml:

bash
# .env
WEB_PORT=8080

2. Provide a default value:

yaml
services:
  web:
    ports:
      - "${WEB_PORT:-8080}:3000"  # Uses 8080 if WEB_PORT is unset

3. Export the variable before running docker-compose:

bash
export WEB_PORT=8080
docker-compose up

Note: env_file in docker-compose.yml only sets variables inside the container, not for the compose file parsing.

3Verify port format syntax

Ensure your port mappings follow valid formats:

yaml
# Valid short syntax formats
ports:
  - "3000"                    # Container port only (Docker assigns host port)
  - "3000-3005"               # Container port range
  - "8000:8000"               # HOST:CONTAINER
  - "9090-9091:8080-8081"     # Port ranges (same count required)
  - "127.0.0.1:8001:8001"     # IP:HOST:CONTAINER
  - "6060:6060/udp"           # With protocol
  - "127.0.0.1::3000"         # IP::CONTAINER (random host port)

# INVALID formats
ports:
  - "8080/udp:8080/udp"       # Wrong! Protocol goes at the end
  - "8080:8080:8080"          # Wrong! Too many colons
  - "8080:"                   # Wrong! Missing container port
  - ":8080"                   # Wrong! Missing host port

For UDP ports, the protocol applies to the entire mapping:

yaml
ports:
  - "12201:12201/udp"  # Correct UDP syntax
4Use long-form port syntax for complex cases

The long-form syntax is more explicit and avoids parsing issues:

yaml
services:
  web:
    ports:
      - target: 80
        published: 8080
        protocol: tcp
        mode: host

  dns:
    ports:
      - target: 53
        published: 5353
        protocol: udp

Long-form fields:
- target: Container port (required)
- published: Host port (optional, Docker assigns if omitted)
- protocol: tcp or udp (default: tcp)
- host_ip: Host IP to bind (default: 0.0.0.0)
- mode: host or ingress (for Swarm)

This syntax eliminates YAML parsing ambiguity entirely.

5Check for port range errors

If using port ranges, ensure they're valid:

yaml
# WRONG: Start port greater than end port
ports:
  - "8082-8080:3002-3000"

# WRONG: Mismatched range sizes
ports:
  - "8080-8082:3000-3001"  # 3 ports to 2 ports

# CORRECT: Valid range with matching sizes
ports:
  - "8080-8082:3000-3002"  # 3 ports to 3 ports

Port ranges must:
- Have start port <= end port
- Have the same number of ports on both sides of the colon

6Fix Dockerfile ENV syntax issues

If ports come from Dockerfile ARG/ENV values, check for syntax errors:

dockerfile
# WRONG: Spaces around equals sign
ENV PORT = 3000
EXPOSE $PORT  # Results in "Invalid containerPort: ="

# CORRECT: No spaces
ENV PORT=3000
EXPOSE $PORT

# Or use braces for clarity
ENV PORT=3000
EXPOSE ${PORT}

Rebuild the image after fixing:

bash
docker-compose build --no-cache
docker-compose up
7Remove port mappings when using host network mode

Port mappings are incompatible with network_mode: host:

yaml
# WRONG: Cannot use both
services:
  web:
    network_mode: host
    ports:
      - "8080:80"  # Invalid with host network

# CORRECT: Host mode - no port mapping needed
services:
  web:
    network_mode: host
    # Container uses host's network directly
    # Access via whatever port the app listens on

# OR: Use bridge mode with port mapping
services:
  web:
    ports:
      - "8080:80"  # Works with default bridge network

With host network mode, the container shares the host's network namespace directly, making port mapping unnecessary and invalid.

Advanced notes

### Understanding YAML Base-60 Parsing

YAML interprets certain numeric patterns as sexagesimal (base-60) values, a legacy feature for time representation. The format xx:yy where yy < 60 is parsed as xx * 60 + yy:

yaml
# Without quotes, these are interpreted as numbers:
80:25   # = 80 * 60 + 25 = 4825
22:22   # = 22 * 60 + 22 = 1342
3:00    # = 3 * 60 + 0 = 180

This is why "8025:25" works but 8025:25 may fail with strange port numbers.

### Version-Specific Issues

Several docker-compose versions had bugs with port parsing:

- v1.12.0: Broke ip::containerPort syntax
- v1.13.0: Introduced "None" errors when inheriting ports
- v1.14.0: Issues with UDP port syntax

If you suspect a version bug:

bash
docker-compose version
# Consider upgrading or using a known stable version
pip install docker-compose==1.29.2  # Last v1 stable

### Debugging Port Configuration

Validate your compose file before running:

bash
# Check the parsed configuration
docker-compose config

# Look specifically at ports
docker-compose config | grep -A 5 "ports:"

If the output shows unexpected values, you've found the parsing issue.

### Expose vs Ports

Don't confuse expose with ports:

yaml
services:
  web:
    expose:
      - "3000"  # Only accessible to linked services
    ports:
      - "8080:3000"  # Accessible from host

expose doesn't publish to the host - it just documents which ports the container listens on and makes them available to other containers on the same network.

### Port Specification in Docker Swarm

When deploying to Swarm, additional port modes apply:

yaml
services:
  web:
    ports:
      - target: 80
        published: 8080
        mode: ingress  # Load balanced across all nodes (default)

      - target: 9090
        published: 9090
        mode: host     # Only on the node running the task

Invalid mode values will cause port specification errors in Swarm deployments.

Frequently asked questions

What does "ERROR: for web Cannot create container for service web: invalid port s" mean?
yml file. 1:8080:80). When the configuration doesn't match these expected patterns, or when YAML parsing produces unexpected values, Docker rejects the specification.
How do I fix "ERROR: for web Cannot create container for service web: invalid port s"?
The 'invalid port specification' error occurs when Docker Compose cannot parse your port mapping syntax. This typically happens due to unquoted port values, undefined environment variables, or malformed port formats. Fix it by quoting ports as strings and validating your syntax.
What causes "ERROR: for web Cannot create container for service web: invalid port s"?
Port values not quoted as strings in docker-compose.yml (YAML base-60 parsing issue) Environment variable for port is undefined or empty, resulting in 'None' Invalid port format: missing colon, extra colons, or typos
Is the "ERROR: for web Cannot create container for service web: invalid port s" error serious?
It is a medium-severity error โ€” more of a blocker than a risk. The steps above resolve it.

Official resources & further reading