GoogleContainerTools / jib

🏗 Build container images for your Java applications.
Apache License 2.0
13.7k stars 1.44k forks source link

Jib fails with BLOB_UPLOAD_UNKNOWN error on Sonatype Nexus #2372

Closed SniXosha closed 4 years ago

SniXosha commented 4 years ago

Environment:

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 commented 4 years ago

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., https://github.com/GoogleContainerTools/jib/issues/1986#issuecomment-536905823 and https://github.com/GoogleContainerTools/jib/issues/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 https://github.com/GoogleContainerTools/jib/issues/2270#issuecomment-584177904.

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 commented 4 years ago

Then configure your build script to use this SNAPSHOT as explained in https://github.com/GoogleContainerTools/jib/issues/2270#issuecomment-584177904.

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

chanseokoh commented 4 years ago

Note to myself:

SniXosha commented 4 years ago

I've managed to get network logs, but it's quite big (~700Kb) to paste it here. Do you want to see a specific section from logs or should I share the whole file? If so, what is the preferable way to share a file?

chanseokoh commented 4 years ago

GitHub allows uploading a file by drag-and-dropping into a comment input box. You can do so if the file doesn't have any sensitive info.

SniXosha commented 4 years ago

network.log

chanseokoh commented 4 years ago

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 commented 4 years ago

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 commented 4 years ago

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

chanseokoh commented 4 years ago

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 commented 4 years ago

It's Sonatype Nexus

chanseokoh commented 4 years ago

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 commented 4 years ago

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

johnburbridge commented 11 months ago

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 commented 10 months ago

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>
stephan-roolvink commented 8 months ago

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

MrPowerGamerBR commented 3 months ago

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 commented 3 months ago

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 commented 3 months ago

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 commented 2 months ago

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:

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.