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

Jib fails with BLOB_UPLOAD_UNKNOWN error on Sonatype Nexus #2372

Closed
SniXosha opened this issue Mar 31, 2020 · 20 comments
Closed

Jib fails with BLOB_UPLOAD_UNKNOWN error on Sonatype Nexus #2372

SniXosha opened this issue Mar 31, 2020 · 20 comments

Comments

@SniXosha
Copy link

Environment:

  • Jib version: 2.1.0
  • Build tool: gradle 6.2
  • OS: Linux/macOS

Description of the issue:
Jib fails with BLOB_UPLOAD_UNKNOWN error.
I have a gradle project with about 15 submodules and I want to push images in our private registry. When I run jib for all sumbodules in my gradle project, sometimes this error occurs. Jib doesn't fail immediately, it's often able to create and push image for about 12-13 submodules and only then it crashes. If I rerun jib after waiting a few seconds, all the remaining submodules are processed successfully (currently, this is my workaround).
I asked people responsible for our registry and they said that this is probably jib's problem, because they have not encountered this error using docker cli.
They also suggested to disable parallel execution in gradle, which seemingly made jib more stable, but didn't solve the problem completely.

Execution failed for task ':submodule:jib'.

> com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Tried to push BLOB for <remote image url> with digest sha256:277866581d95cdba21d952e55187c0bced4a1f7f0016d3fc2195616f0ab85744 but failed because: other: blob upload unknown to registry | If this is a bug, please file an issue at https://github.com/GoogleContainerTools/jib/issues/new

Expected behavior:
Jib runs successfully regardless of number of modules/execution time without BLOB_UPLOAD_UNKNOWN error.

Steps to reproduce:

  1. Create a project with a lot of submodules
  2. Run jib
  3. Jib fails after processing significant amount of sumbodules

jib-gradle-plugin Configuration:

jib {
    from {
        image registryBaseImage
        auth {
            username registryUsername
            password registryPassword
        }
    }
    to {
        image registryRepository + project.name + ':' + project.version
        auth {
            username registryUsername
            password registryPassword
        }
    }
}

Log output:

FAILURE: Build failed with an exception.



* What went wrong:

Execution failed for task ':submodule:jib'.

> com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Tried to push BLOB for <remote image url> with digest sha256:277866581d95cdba21d952e55187c0bced4a1f7f0016d3fc2195616f0ab85744 but failed because: other: blob upload unknown to registry | If this is a bug, please file an issue at https://github.com/GoogleContainerTools/jib/issues/new



* Try:

Run with --info or --debug option to get more log output. Run with --scan to get full insights.



* Exception is:

org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':submodule:jib'.

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:205)

	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:263)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:203)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:184)

	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:114)

	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)

	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:62)

	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)

	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)

	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)

	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)

	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)

	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:416)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:406)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:102)

	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)

	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)

	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:41)

	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:372)

	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:359)

	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:352)

	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:338)

	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:127)

	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:191)

	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:182)

	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:124)

	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)

	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)

	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)

Caused by: org.gradle.internal.UncheckedException: com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Tried to push BLOB for <remote image url> with digest sha256:277866581d95cdba21d952e55187c0bced4a1f7f0016d3fc2195616f0ab85744 but failed because: other: blob upload unknown to registry | If this is a bug, please file an issue at https://github.com/GoogleContainerTools/jib/issues/new

	at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:67)

	at org.gradle.internal.UncheckedException.throwAsUncheckedException(UncheckedException.java:41)

	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:107)

	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:49)

	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:42)

	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:28)

	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:727)

	at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:694)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$3.run(ExecuteActionsTaskExecuter.java:568)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:402)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:394)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:165)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:250)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:158)

	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:92)

	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.run(DelegatingBuildOperationExecutor.java:31)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:553)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:536)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.access$300(ExecuteActionsTaskExecuter.java:109)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.executeWithPreviousOutputFiles(ExecuteActionsTaskExecuter.java:276)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$TaskExecution.execute(ExecuteActionsTaskExecuter.java:265)

	at org.gradle.internal.execution.steps.ExecuteStep.lambda$execute$1(ExecuteStep.java:33)

	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:33)

	at org.gradle.internal.execution.steps.ExecuteStep.execute(ExecuteStep.java:26)

	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:67)

	at org.gradle.internal.execution.steps.CleanupOutputsStep.execute(CleanupOutputsStep.java:36)

	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:49)

	at org.gradle.internal.execution.steps.ResolveInputChangesStep.execute(ResolveInputChangesStep.java:34)

	at org.gradle.internal.execution.steps.CancelExecutionStep.execute(CancelExecutionStep.java:43)

	at org.gradle.internal.execution.steps.TimeoutStep.executeWithoutTimeout(TimeoutStep.java:73)

	at org.gradle.internal.execution.steps.TimeoutStep.execute(TimeoutStep.java:54)

	at org.gradle.internal.execution.steps.CatchExceptionStep.execute(CatchExceptionStep.java:34)

	at org.gradle.internal.execution.steps.CreateOutputsStep.execute(CreateOutputsStep.java:44)

	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:54)

	at org.gradle.internal.execution.steps.SnapshotOutputsStep.execute(SnapshotOutputsStep.java:38)

	at org.gradle.internal.execution.steps.BroadcastChangingOutputsStep.execute(BroadcastChangingOutputsStep.java:49)

	at org.gradle.internal.execution.steps.CacheStep.executeWithoutCache(CacheStep.java:153)

	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:67)

	at org.gradle.internal.execution.steps.CacheStep.execute(CacheStep.java:41)

	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:44)

	at org.gradle.internal.execution.steps.StoreExecutionStateStep.execute(StoreExecutionStateStep.java:33)

	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:38)

	at org.gradle.internal.execution.steps.RecordOutputsStep.execute(RecordOutputsStep.java:24)

	at org.gradle.internal.execution.steps.SkipUpToDateStep.executeBecause(SkipUpToDateStep.java:92)

	at org.gradle.internal.execution.steps.SkipUpToDateStep.lambda$execute$0(SkipUpToDateStep.java:85)

	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:55)

	at org.gradle.internal.execution.steps.SkipUpToDateStep.execute(SkipUpToDateStep.java:39)

	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:76)

	at org.gradle.internal.execution.steps.ResolveChangesStep.execute(ResolveChangesStep.java:37)

	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:36)

	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsFinishedStep.execute(MarkSnapshottingInputsFinishedStep.java:26)

	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:94)

	at org.gradle.internal.execution.steps.ResolveCachingStateStep.execute(ResolveCachingStateStep.java:49)

	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:79)

	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:53)

	at org.gradle.internal.execution.steps.ValidateStep.execute(ValidateStep.java:74)

	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.lambda$execute$2(SkipEmptyWorkStep.java:78)

	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:78)

	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:34)

	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:39)

	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:40)

	at org.gradle.internal.execution.steps.LoadExecutionStateStep.execute(LoadExecutionStateStep.java:28)

	at org.gradle.internal.execution.impl.DefaultWorkExecutor.execute(DefaultWorkExecutor.java:33)

	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:192)

	... 30 more

Caused by: com.google.cloud.tools.jib.plugins.common.BuildStepsExecutionException: Tried to push BLOB for <remote image url> with digest sha256:277866581d95cdba21d952e55187c0bced4a1f7f0016d3fc2195616f0ab85744 but failed because: other: blob upload unknown to registry | If this is a bug, please file an issue at https://github.com/GoogleContainerTools/jib/issues/new

	at com.google.cloud.tools.jib.plugins.common.JibBuildRunner.runBuild(JibBuildRunner.java:278)

	at com.google.cloud.tools.jib.gradle.BuildImageTask.buildImage(BuildImageTask.java:110)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)

	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:104)

	... 91 more

Caused by: com.google.cloud.tools.jib.registry.RegistryErrorException: Tried to push BLOB for <remote image url> with digest sha256:277866581d95cdba21d952e55187c0bced4a1f7f0016d3fc2195616f0ab85744 but failed because: other: blob upload unknown to registry | If this is a bug, please file an issue at https://github.com/GoogleContainerTools/jib/issues/new

	at com.google.cloud.tools.jib.registry.RegistryErrorExceptionBuilder.build(RegistryErrorExceptionBuilder.java:105)

	at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.newRegistryErrorException(RegistryEndpointCaller.java:207)

	at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:154)

	at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:115)

	at com.google.cloud.tools.jib.registry.RegistryClient.callRegistryEndpoint(RegistryClient.java:603)

	at com.google.cloud.tools.jib.registry.RegistryClient.pushBlob(RegistryClient.java:545)

	at com.google.cloud.tools.jib.builder.steps.PushBlobStep.call(PushBlobStep.java:89)

	at com.google.cloud.tools.jib.builder.steps.PushLayerStep.call(PushLayerStep.java:93)

	at com.google.cloud.tools.jib.builder.steps.PushLayerStep.call(PushLayerStep.java:33)

	at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:125)

	at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:69)

	at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)

Caused by: com.google.cloud.tools.jib.http.ResponseException: 404 Not Found

{"errors":[{"code":"BLOB_UPLOAD_UNKNOWN","message":"blob upload unknown to registry","detail":"Missing upload with uuid: a9c1d102-00d7-4957-8fd0-a0b85a164072"}]}

	at com.google.cloud.tools.jib.http.FailoverHttpClient.call(FailoverHttpClient.java:323)

	at com.google.cloud.tools.jib.http.FailoverHttpClient.call(FailoverHttpClient.java:244)

	at com.google.cloud.tools.jib.registry.RegistryEndpointCaller.call(RegistryEndpointCaller.java:139)

	... 9 more

Caused by: com.google.api.client.http.HttpResponseException: 404 Not Found

{"errors":[{"code":"BLOB_UPLOAD_UNKNOWN","message":"blob upload unknown to registry","detail":"Missing upload with uuid: a9c1d102-00d7-4957-8fd0-a0b85a164072"}]}

	at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1113)

	at com.google.cloud.tools.jib.http.FailoverHttpClient.call(FailoverHttpClient.java:317)

	... 11 more

Additional Information:

I asked people responsible for our registry and they said that this is probably jib's problem, because they have not encountered this error using docker cli.
They also suggested to disable parallel execution in gradle, which seemingly made jib more stable, but didn't solve the problem completely.

@chanseokoh
Copy link
Member

chanseokoh commented Mar 31, 2020

Hi @SniXosha,

I've looked into our code to see where this might potentially fail. I can think of one hypothetical scenario. However, I'm still not convinced of my scenario, because it is unrelated to the level of concurrency; in my scenario, your registry should occasionally fail regardless of whether Jib pushes concurrently or serially. Therefore, my scenario is in conflict with your account that disabling parallel execution seemingly made it more stable. (In any case, my scenario is still not about the fault of Jib but the server not conforming to the HTTP standard.) (UPDATE: turned out to be a bug in Nexus.)

If that is not the case, I am highly suspicious of the server malfunctioning. In the past, we often did see confirmed cases of server issues in some popular registries when there is a very high level of concurrency (e.g., #1986 (comment) and #2013). From our track record, there's a high chance that this is a server issue. (BTW, Docker CLI by default doesn't allow the same level of high concurrency that Jib outputs.)

Anyways, it will become obvious once I can get low-level HTTP request/response logs. Unfortunately, Jib Gradle has an issue generating HTTP logs, so I need your help to build a Jib Gradle plugin from a patched source. Don't be scared, it's very easy to build Jib from source: (UPDATE: patching no longer needed with newer Jib versions.)

$ git clone https://github.com/GoogleContainerTools/jib.git
$ cd jib
$ ./gradlew :jib-gradle-plugin:install

This will build Jib 2.1.1-SNAPSHOT and install it into your local Maven repo (~/.m2/repository). Then configure your build script to use this SNAPSHOT as explained in #2270 (comment).

Then follow these instructions to capture detailed HTTP logs, except passing -Djib.serialize=true. Using -Djib.serialize=true disables parallel pushes, so we don't want that. If everything is set correctly, you'll see logs like

Mar 31, 2020 9:55:52 AM com.google.api.client.http.HttpResponse <init>
CONFIG: -------------- RESPONSE --------------
HTTP/1.1 202 Accepted
Content-Length: 0
Docker-Distribution-Api-Version: registry/2.0
Docker-Upload-Uuid: 6292f0d7-93cb-4a8e-8336-78a1bf7febd2
Location: https://registry-1.docker.io/v2/francium25/test/blobs/uploads/6292f0d7-93cb-4a8e-8336-78a1bf7febd2?_state=6lvUYgy-Xw0N3L5SVgciJGhhUO928fGfHS35zpGIiJx7Ik5hbWUiOiJmcmFuY2l1bTI1L3Rlc3QiLCJVVUlEIjoiNjI5MmYwZDctOTNjYi00YThlLTgzMzYtNzhhMWJmN2ZlYmQyIiwiT2Zmc2V0Ijo2NTcyOTMsIlN0YXJ0ZWRBdCI6IjIwMjAtMDMtMzFUMTM6NTU6NTBaIn0%3D
Range: 0-657292
Date: Tue, 31 Mar 2020 13:55:52 GMT
Strict-Transport-Security: max-age=31536000

Mar 31, 2020 9:55:52 AM com.google.api.client.http.HttpRequest execute
CONFIG: -------------- REQUEST  --------------
PUT https://registry-1.docker.io/v2/francium25/test/blobs/uploads/6292f0d7-93cb-4a8e-8336-78a1bf7febd2?_state=6lvUYgy-Xw0N3L5SVgciJGhhUO928fGfHS35zpGIiJx7Ik5hbWUiOiJmcmFuY2l1bTI1L3Rlc3QiLCJVVUlEIjoiNjI5MmYwZDctOTNjYi00YThlLTgzMzYtNzhhMWJmN2ZlYmQyIiwiT2Zmc2V0Ijo2NTcyOTMsIlN0YXJ0ZWRBdCI6IjIwMjAtMDMtMzFUMTM6NTU6NTBaIn0%3D&digest=sha256:24f0c933cbef83faee52f82c7f889c727b1ece5123b92d036c52fa865480f037
Accept:
Accept-Encoding: gzip
Authorization: <Not Logged>
User-Agent: jib 2.1.1-SNAPSHOT jib-maven-plugin Google-HTTP-Java-Client/1.34.0 (gzip)

Please let me know once you get the network logs for the error.

@chanseokoh
Copy link
Member

chanseokoh commented Mar 31, 2020

Then configure your build script to use this SNAPSHOT as explained in #2270 (comment).

Oh, depending on how you set up your multi-module project, you may need to adjust the buildscript accordingly.

For example, if you are not applying Jib globally on the root project (that is, you have apply false as plugins { id '...jib' apply false } in the root build.gradle) but instead apply Jib individually in each sub-module, then for applying a SNAPSHOT version, you would

  • only declare the buildscript block for the Jib classpath in the root build.gradle
  • not put apply plugin in the root build.gradle
  • instead, put apply plugin only in each sub-module (in place of plugins { id '...jib' })

@chanseokoh

This comment has been minimized.

@SniXosha

This comment has been minimized.

@chanseokoh

This comment has been minimized.

@SniXosha
Copy link
Author

network.log

@chanseokoh
Copy link
Member

chanseokoh commented Mar 31, 2020

Sorry, could you enable debug logging (--debug) to include timing information? Looking at the log, it does look like a server fault. But I'm trying to rule out the hypothesis that the server imposes some internal timeout for completing a transaction.

Oh, sorry, forget it. I already have timestamps. Let me get back to you real soon.

@chanseokoh
Copy link
Member

chanseokoh commented Mar 31, 2020

This proves that your registry is malfunctioning.

  1. Jib sends PATCH (streaming a blob layer upload).
    -------------- REQUEST  --------------
    PATCH https://my.reigstry/v2/repo/fork-patcher/blobs/uploads/e6bd15cf-0c3e-40a2-b128-08a568023f6c
    ...
    Content-Type: application/octet-stream
    
  2. The registry completes reading the stream and returns OK (202 Accepted) at 19:06:48. The registry returns with the upload UUID e6bd15cf-0c3e-40a2-b128-08a568023f6c for this layer upload, as expected. It also continues to return the same upload URL of /v2/repo/fork-patcher/blobs/uploads/e6bd15cf-0c3e-40a2-b128-08a568023f6c via the Location: header.
    -------------- RESPONSE --------------
    HTTP/1.1 202 Accepted
    ...
    Date: Tue, 31 Mar 2020 19:06:48 GMT
    ...
    Docker-Upload-UUID: e6bd15cf-0c3e-40a2-b128-08a568023f6c
    Location: /v2/repo/fork-patcher/blobs/uploads/e6bd15cf-0c3e-40a2-b128-08a568023f6c
    
  3. Within a second after getting the OK response, Jib issues a commit (final zero-byte-body PUT to complete a layer upload) at the requested upload URL it has been using. Notice the URL is correct.
    -------------- REQUEST  --------------
    PUT https://my.reigstry/v2/repo/fork-patcher/blobs/uploads/e6bd15cf-0c3e-40a2-b128-08a568023f6c?digest=sha256:b0d03fa3137b59f53b5553ffbed0aca17b8427e6f153b99ecc09725c88ab3f03
    ...
    
  4. However, the server unexpectedly returns 404. This doesn't make sense at all. The server must accept it. Note the timestamp and the UUID in the error message.
    -------------- RESPONSE --------------
    HTTP/1.1 404 Not Found
    ...
    Date: Tue, 31 Mar 2020 19:06:49 GMT
    ...
    Total: 161 bytes
    {"errors":[{"code":"BLOB_UPLOAD_UNKNOWN","message":"blob upload unknown to registry","detail":"Missing upload with uuid: e6bd15cf-0c3e-40a2-b128-08a568023f6c"}]}
    

You should contact the registry people and present this evidence that proves that the server is not working correctly.

@SniXosha
Copy link
Author

Thanks for clarification! I'll try to contact them.

@chanseokoh
Copy link
Member

If you need assistance, let me know. And please update here once you have more information. That said, what's your registry (Sonatype Nexus, Quay, Harbor, Docker Distribution, etc.)?

@SniXosha
Copy link
Author

It's Sonatype Nexus

@chanseokoh
Copy link
Member

Other people did encounter this problem (also with Docker CLI), and there's an open issue on Sonatype Nexus.

[NEXUS-20640] docker push may fail with blob upload unknown due to race condition

As such, I'll close the issue, but feel free to update or re-open as necessary.

@chanseokoh
Copy link
Member

Just got the notification that the Sonatype Nexus bug (NEXUS-20640) is marked fixed.

@johnburbridge
Copy link

Adding that this seems to affect ghcr.io (Github Container Registry) as well. Adding -Djib.serialize=true to ./gradlew jib allowed it to succeed.

@DmitryTen
Copy link

Hi guys, does anybody still has this issue?
We are using Nexus OSS 3.38.1-01 (which is not that old, and should contain the fix), but we still encounter this issue.
I also tried to use the -Djib.serialize=true, which seems to help in the beginning but now it fails with -Djib.serialize=true also.
we use:

Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Java version: 21.0.1, vendor: Amazon.com Inc., runtime: /usr/lib/jvm/java-21-amazon-corretto
OS name: "linux", version: "4.14.304-226.531.amzn2.x86_64", arch: "amd64", family: "unix"

  <plugin>
    <groupId>com.google.cloud.tools</groupId>
    <artifactId>jib-maven-plugin</artifactId>
    <version>3.3.2</version>
  </plugin>

nitram509 added a commit to camunda-community-hub/zeebe-simple-monitor that referenced this issue Feb 19, 2024
@stephan-roolvink
Copy link

For us, the -Djib.serialize=true is also not working, we are using jib 3.4.1.

@MrPowerGamerBR
Copy link

I can also confirm the same issue when uploading packages to GitHub, and in my experience using -Djib.serialize=true didn't fix it

What I have noticed is that all jib tasks that fail, seems to fail after trying to retry an upload

PUT https://ghcr.io/v2/lorittabot/loritta-morenitta/blobs/upload/82fcebf5-3069-4240-8d7a-98b16d5aadea?digest=sha256:bb08c4be5c13447163f30047ad3bd7d058eae734846b5a68d83133f4ad720448 failed and will be retried

@MrPowerGamerBR
Copy link

Just something worth nothing that I found out: I think that this is a ghcr.io issue, in my project I have multiple submodules that are uploaded to ghcr.io via jib, and using -Djib.serialize=true doesn't seem to fix the issue because the jib tasks are still executed in parallel, so what I did for now is to not parallelize the jib tasks by invoking gradlew separately for each jib task, and that seems to fix the issue, or at the very least, I haven't experienced any tasks yet.

@MrPowerGamerBR
Copy link

MrPowerGamerBR commented Aug 13, 2024

Update to my previous comment: That didn't fix the issue... it does help a lot, but it didn't fully fix the issue.

What I'm currently testing is running the jib tasks in separate steps AND using -Djib.serialize=true, currently haven't had any issues... yet. Whoops I actually experienced a build fail right after I posted this comment smh. One thing worth noting is that I had other GitHub Actions builds running at the same time, maybe that could be why...?

@KRK1ST
Copy link

KRK1ST commented Aug 28, 2024

I have raised an issue to the github support team regarding this issue we experienced with ghcr.io and got a quite thorough response with investigation from their engineering team, I'll paraphrase:

  • This issue seems to appear on multiple platforms which leads them to believe it is a issue with Jib

also from my support ticket: "one theory being that Jib may be retrying an upload before the previous upload has actually failed. This could also explain the inconsistency of failure you are seeing, as different uploads would take different amounts of time, and thus some would fit within the retry window (thus not failing), while a few might exceed the retry window and thus fail."

Since this issue is already closed we probably need to open a new one if we want anything further to happen.

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

No branches or pull requests

7 participants