Symptom
Uploads of files to Nexus Repository 3 fail with "broken pipe" errors visible in the client logs.
Cause
Most clients that upload files to Nexus Repository 3 use what is known as non-preemptive authentication. This means they will first attempt the upload without sending login credentials. Nexus Repository will respond tho this with an HTTP 401 (unauthorized) response, and send the client a WWW-Authenticate header indicating it needs to send login credentials. The client will then send the upload again, this time with credentials.
Older versions of Nexus (the 2.x series) would let the first upload complete before sending the 401 response. Nexus 3 will send the 401 response right away, which saves the overhead of having the client send their entire upload twice. Sending 401 in this case is legal, but some clients are not able to handle this correctly. Those clients will see the socket closed when Nexus sends it's response, and will not bother to read the reply, they will instead exit with errors.
Resolution
The workaround is to have Nexus Repository consume all content before issuing a 401 with an authorization challenge. This causes a performance hit, so we decided to implement it by default only for Maven since it is known to be affected by this problem.
The clients that will get this workaround is determined by a system property. This property lists user agents that should have this specific treatment. The default value for this is:
nexus.view.exhaustForAgents=-Apache-Maven.*|Apache Ivy.*
The format of the property is a regular expressions delimitated by pipe ('|') characters that will match against user agent strings.
If you're encountering the above issue with a client that is not Maven, you'll first need to determine what user agent string is sent with its requests. Look for PUT requests that are receiving 401 responses. The user agent string will be in the last column, as in this example:
192.168.1.167 - - [20/Apr/2017:12:25:27 -0600] "PUT /repository/releases/org/foo/project/1.0.0/project-1.0.0.jar HTTP/1.1" 401 0 19 ""maven-artifact/3.0.4 (Java)"
Once you have this information, edit "sonatype-work/nexus3/etc/nexus.properties" and add a line like the following:
nexus.view.exhaustForAgents=Apache-Maven.*|Apache Ivy.*|maven\-artifact.*
The above will tell Nexus Repository to read all content before sending the 401 response for requests that have user agent strings which start with Apache-Maven
or Apache Ivy
. or maven-artifact.
What if my user agent contains a pipe | character - how do I escape it?
The character sequence \\s,\\s
can also be used as a delimiter to separate distinct regular expression patterns in the case one of your user agent patterns contains a pipe |. The pattern (regex)\\s,\\s(regex) causes Nexus to treat the property value as equivalent to a Pattern compiled with (regex)|(regex) .