Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port out of bounds gives error 'invalid publish opts format' #1962

Closed
carlosen14 opened this issue Jun 20, 2019 · 9 comments · Fixed by #2251
Closed

Port out of bounds gives error 'invalid publish opts format' #1962

carlosen14 opened this issue Jun 20, 2019 · 9 comments · Fixed by #2251

Comments

@carlosen14
Copy link

Description

When run with a port out of bounds throws wrong error saying about options format instead of say port does not exist, or something related.

Steps to reproduce the issue:

  1. run docker run -it -p 80801:80 --rm nginx:1.17.0-alpine /bin/sh

Describe the results you received:
docker: invalid publish opts format (should be name=value but got '80801:80').
See 'docker run --help'.

Describe the results you expected:
docker: invalid port '80801:80'.

Additional information you deem important (e.g. issue happens only occasionally):
first time happens.
if run docker run -it -p 10801:80 --rm nginx:1.17.0-alpine /bin/sh. works!

invalid publish opts format (should be name=value but got '80801:80'). has nothing to do with the problem.

Output of docker version:

Client:
 Version:           18.09.6
 API version:       1.38 (downgraded from 1.39)
 Go version:        go1.10.8
 Git commit:        481bc77
 Built:             Sat May  4 02:35:57 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.4
  Git commit:       e68fc7a
  Built:            Tue May  7 17:57:34 2019
  OS/Arch:          linux/amd64
  Experimental:     false

Output of docker info:

Containers: 24
 Running: 11
 Paused: 0
 Stopped: 13
Images: 382
Server Version: 18.06.1-ce
Storage Driver: aufs
 Root Dir: /var/snap/docker/common/var-lib-docker/aufs
 Backing Filesystem: extfs
 Dirs: 641
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file logentries splunk syslog
Swarm: error
 NodeID: 
 Error: manager stopped: failed to listen on remote API address: listen tcp 0.0.0.0:2377: bind: address already in use
 Is Manager: false
 Node Address: 192.168.15.10
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 468a545b9edcd5932818eb9de8e72413e616e86e
runc version: N/A (expected: 69663f0bd4b60df09991c08812a60108003fa340)
init version: 949e6fa (expected: fec3683)
Security Options:
 apparmor
 seccomp
  Profile: default
Kernel Version: 4.18.0-21-generic
Operating System: Ubuntu Core 16
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 62.64GiB
Name: carlos-lenovo
ID: F2JD:NC3H:VAFO:CZVL:2XRJ:FY3Q:TQWW:SFJ2:CTFL:7V5T:EV3G:BDT6
Docker Root Dir: /var/snap/docker/common/var-lib-docker
Debug Mode (client): false
Debug Mode (server): true
 File Descriptors: 110
 Goroutines: 119
 System Time: 2019-06-20T13:26:43.012530765-05:00
 EventsListeners: 0
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false

WARNING: No swap limit support
@thaJeztah
Copy link
Member

Thanks for reporting; I see where the problem is, but it looks like it needs some refactoring;

The current code first attempts to parse the -p / --publish using the shorthand notation (-p 8080:80);

ports, portBindings, err = nat.ParsePortSpecs(publishOpts)
// If simple port parsing fails try to parse as long format
if err != nil {

If that parsing fails, it assumes it's because the user used the advanced/long-hand notation (-p target=8080,published=80), and continues parsing that format; that will fail again, because the flag is not using a comma-separated list of options;

opt := strings.Split(param, "=")
if len(opt) < 2 {
return optsList, errors.Errorf("invalid publish opts format (should be name=value but got '%s')", param)
}

And then it returns that error ("should be name=value").

I see that the current logic has another problem; because all options are parsed either as shorthand or as longhand, you cannot combine the shorthand and longhand form, so this also fails currently:

In this case, both options are valid, but don't work when combined;

# valid
docker run --rm -p 8080:80 busybox

# also valid
docker run --rm -p target=8081,published=81 busybox

# produces an error:
docker run --rm -p 8080:80 -p target=8081,published=81 busybox

docker: invalid publish opts format (should be name=value but got '8080:80').

So, what I think is needed is:

  1. only loop through the options once
  2. try parsing each item in the list first as "shorthand", then as "advanced" (this allows combining both forms)
  3. be smarter in detecting shorthand/advanced notation: if there's no = in the value, it cannot be the advanced notation; in that case, return the original error of the shorthand parsing.

NullHypothesis added a commit to NullHypothesis/community that referenced this issue Aug 9, 2019
The instructions stopped working because docker messed up its command
line parsing: <docker/cli#1962>

Besides, lektor doesn't like backslashes in code blocks.
This was referenced Aug 11, 2019
@jpninanjohn
Copy link

Is this still an issue?

@scippio
Copy link

scippio commented Oct 8, 2019

🤦‍♂️

@pymhd
Copy link

pymhd commented Oct 22, 2019

#2151

@lflucasferreira
Copy link

I still get this problem.

Today I tried:

docker run --name redisinsight_rci -p 80010:8001 -dit -v redisinsight:/db redislabs/redisinsight

So I was forced to use another port, in this case, 8100:8001

@thaJeztah
Copy link
Member

@lflucasferreira the fix is only in master currently, but port 80010 is invalid (the RFC describes port numbers are 16 bit, so the maximum port number is 65535)

@DevinCampbell
Copy link

DevinCampbell commented Oct 4, 2020

This problem is still extant. Running docker create \ --publish=8096:8096 \ --publish=8920:8920 \ --publish=7359/udp:7359/udp \ --publish=1900/udp:1900/udp \ -v /var/devin/jellyfin:/config \ -v /media/mergerfsjbod/plex/tv_shows:/data/tvshows \ -v /media/mergerfsjbod/plex/movies:/data/movies \ -v /media/mergerfsjbod/plex/anime:/data/anime \ -v /media/mergerfsjbod/plex/cartoons:/data/cartoons \ -e PUID=1000 \ -e PGID=1000 \ -e TZ=America/Chicago \ -e UMASK_SET=022 \ --name=jellyfin \ --restart=always \ linuxserver/jellyfin

Gives docker: invalid publish opts format (should be name=value but got '8096:8096').

It also occurs if I use -p instead of --publish=

@thaJeztah
Copy link
Member

@DevinCampbell #2251 is not in a 19.03.x release, and will be in the upcoming 20.x release

@thaJeztah
Copy link
Member

Actually, looks like your issue is in --publish=7359/udp:7359/udp, which should be --publish=7359:7359/udp (/udp at the end, not after the first port). With the changes from , the error message is somewhat clearer (but could still use some tweaking to also mention the shorthand notation);

docker create -p 7359/udp:7359/udp nginx:alpine
docker: invalid publish opts format (should be name=value but got '7359/udp:7359/udp').
See 'docker create --help'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
7 participants