Issues
Issues copied to clipboard
Public Docker Hub OCI registry now needs access token and username inputting into the External Feed in Octopus
Severity
Not blocking customers but they now need to create a free DockerHub account and generate a PAT to be able to pull helm charts from Public Docker Repo
Version
2024.2.9391 / 2024.3.10989
Latest Version
I could reproduce the problem in the latest build
What happened?
Previously, customers could authenticate anonymously to the Public Docker Hub Repo using an OCI Registry Feed in Octopus (not require a Username/Password in the External Feed setup in Octopus) as per our documentation on OCI Registry Feeds.
However, now when you try and pull a helm chart you see this error on the create release page:
Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation
We required the ability to download the manifest file for us to be able to validate the container correctly and this no longer works unauthenticated.
Please see workaround below to get you up and running again.
Reproduction
- Create a new external feed of type
OCI Registry Feedin Octopus and use our documentation here to set it up for a Public Docker Hub repository. Ensure you save the feed (you won't be able to save and test). - Create a new project and include a
Deploy a Helm ChartStep. - For the Chart Package action in that step chose the OCI Registry Feed we setup in Step 1.
- Physically type the repository and package name in (ie if using our Octopus Helm Chart you need to type
octopusdeploy/octopusdeploy-helm). - Fill in the rest of the chart for deployment and save it.
- Create a release and see the error message.
- Now go back into your External Feeds and use the workaround steps below to add a username and PAT to the feed in Octopus and save it.
- Go to create a release for the same project we create in step 2 and see a version number for that package will now be shown and you can now deploy.
Error and Stacktrace
2024-08-22 09:53:42.3805 3660 104 INFO "HTTP" "GET" to "192.168.0.201""/api/Spaces-1/feeds" "completed" with 200 in 00:00:00.0119649 (11ms) by "octoadmin"
2024-08-22 09:53:42.3805 3660 104 WARN Failed to get authentication header. Assuming this feed does not support search.
System.Exception: Unable to retrieve authentication token required to perform operation.
at Octopus.Core.Packages.Oci.OciRegistryClient.RetrieveAuthenticationToken(String authUrl, NetworkCredential credential, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 361
at Octopus.Core.Packages.Oci.OciRegistryClient.GetAuthRequestHeader(HttpResponseMessage response, NetworkCredential credential, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 369
at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 329
2024-08-22 09:53:42.3805 3660 104 ERROR Unhandled error on request: "Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation."
Octopus.Core.Packages.Docker.DockerRegistrySearchNotSupportedException: Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation.
at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 334
--- End of stack trace from previous location ---
at Octopus.Core.Packages.Oci.OciRegistryClient.Get(Uri url, ICredentials credentials, CancellationToken cancellationToken, Action`1 customAcceptHeader) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 285
at Octopus.Core.Packages.Oci.OciRegistryClient.GetAllPages(Uri url, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 170
at Octopus.Core.Packages.Oci.OciRegistryClient.ListVersions(Uri url, String packageId, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 161
at Octopus.Core.Packages.Oci.OciRegistryPackageFeed.ListVersions(String packageId, ILogger logger, PackageVersionSearchOptions searchOptions, CancellationToken cancellationToken, Int32 skip, Int32 take, Boolean includeReleaseNotes) in ./source/Octopus.Core/Packages/Oci/OciRegistryPackageFeed.cs:line 104
at Octopus.Core.Features.Feeds.GetFeedPackageVersionsRequestHandler.Handle(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Feeds/GetFeedPackageVersionsRequestHandler.cs:line 56
at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Server.Web.Controllers.Feeds.GetFeedPackageVersionsController.GetFeedPackageVersions(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/Feeds/GetFeedPackageVersionsController.cs:line 25
at lambda_method2122224(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Octopus.Server.Web.Middleware.BoundaryTrailerRewriteMiddleware.Invoke(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/BoundaryTrailerRewriteMiddleware.cs:line 45
at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 50
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 31
at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 42
at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 24
at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 50
at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 58
at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, IUserAuthenticator userAuthenticator, IUserSessionService userSessionService, IWebAuthCache authCache, ILogger logger) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 61
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 64
at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 51
2024-08-22 09:53:42.3805 3660 104 INFO "HTTP" "GET" to "192.168.0.201""/api/Spaces-1/feeds/Feeds-1489/packages/versions" "completed" with 500 in 00:00:00.6958322 (695ms) by "octoadmin"
Octopus.Core.Packages.Docker.DockerRegistrySearchNotSupportedException: Failed to get authentication header, this feed may not support search. Unable to retrieve authentication token required to perform operation.
at Octopus.Core.Packages.Oci.OciRegistryClient.<>c__DisplayClass16_0.<<Get>g__GetTokenFromAuthService|0>d.MoveNext() in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 334
--- End of stack trace from previous location ---
at Octopus.Core.Packages.Oci.OciRegistryClient.Get(Uri url, ICredentials credentials, CancellationToken cancellationToken, Action`1 customAcceptHeader) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 285
at Octopus.Core.Packages.Oci.OciRegistryClient.GetAllPages(Uri url, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 170
at Octopus.Core.Packages.Oci.OciRegistryClient.ListVersions(Uri url, String packageId, ICredentials credentials, CancellationToken cancellationToken) in ./source/Octopus.Core/Packages/Oci/OciRegistryClient.cs:line 161
at Octopus.Core.Packages.Oci.OciRegistryPackageFeed.ListVersions(String packageId, ILogger logger, PackageVersionSearchOptions searchOptions, CancellationToken cancellationToken, Int32 skip, Int32 take, Boolean includeReleaseNotes) in ./source/Octopus.Core/Packages/Oci/OciRegistryPackageFeed.cs:line 104
at Octopus.Core.Features.Feeds.GetFeedPackageVersionsRequestHandler.Handle(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Core/Features/Feeds/GetFeedPackageVersionsRequestHandler.cs:line 56
at Octopus.Core.Infrastructure.Mediator.AutofacMediator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.SystemComponentModelValidationDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.FluentValidationsDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Core.Infrastructure.Mediator.Decorators.MessageBusSiphoningDecorator.Request[TRequest,TResponse](IRequest`2 request, CancellationToken cancellationToken)
at Octopus.Server.Web.Controllers.Feeds.GetFeedPackageVersionsController.GetFeedPackageVersions(GetFeedPackageVersionsRequest request, CancellationToken cancellationToken) in ./source/Octopus.Server/Web/Controllers/Feeds/GetFeedPackageVersionsController.cs:line 25
at lambda_method2122224(Closure, Object)
at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|7_0(Endpoint endpoint, Task requestTask, ILogger logger)
at Octopus.Server.Web.Middleware.BoundaryTrailerRewriteMiddleware.Invoke(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/BoundaryTrailerRewriteMiddleware.cs:line 45
at Octopus.Server.Web.Infrastructure.Authentication.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult) in ./source/Octopus.Server/Web/Infrastructure/Authentication/AuthorizationMiddlewareResultHandler.cs:line 50
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 31
at Octopus.Server.Web.UnitOfWorkMiddleware.InvokeAsync(HttpContext httpContext, IUnitOfWork unitOfWork) in ./source/Octopus.Server/Web/UnitOfWorkMiddleware.cs:line 42
at Octopus.Server.Web.Middleware.OctopusClientOldVersionWarningMiddleware.InvokeAsync(HttpContext context, IAutomationContext automationContext) in ./source/Octopus.Server/Web/Middleware/OctopusClientOldVersionWarningMiddleware.cs:line 24
at Octopus.Server.Web.Middleware.DynamicContentHeadersMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/DynamicContentHeadersMiddleware.cs:line 50
at Octopus.Server.Web.Middleware.MaintenanceModeMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/MaintenanceModeMiddleware.cs:line 58
at Octopus.Server.Web.Middleware.OctopusAuthenticationMiddleware.InvokeAsync(HttpContext context, IUserAuthenticator userAuthenticator, IUserSessionService userSessionService, IWebAuthCache authCache, ILogger logger) in ./source/Octopus.Server/Web/Middleware/OctopusAuthenticationMiddleware.cs:line 61
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at Octopus.Server.Web.Middleware.TelemetryMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/TelemetryMiddleware.cs:line 64
at Octopus.Server.Web.Middleware.ErrorHandlingMiddleware.InvokeAsync(HttpContext context) in ./source/Octopus.Server/Web/Middleware/ErrorHandlingMiddleware.cs:line 51
2024-08-22 09:53:42.3805 3660 104 INFO "HTTP" "POST" to "192.168.0.201""/bff/telemetry/recordPortalOperation" "completed" with 200 in 00:00:00.0095793 (9ms) by "octoadmin"
More Information
Initial customer ticket (internal) - https://octopus.zendesk.com/agent/tickets/200053 R and D (internal) - https://octopusdeploy.slack.com/archives/CNHBHV2BX/p1724256060753389
Workaround
For this to work now, you need to create a free Docker Hub account.
From there you need to create a Personal Access Token (PAT) by following Docker's Official Documentation on Create and Manage Access Tokens.
The token itself needs to have Public Repo Read Only access permissions (you can give it any description you want):
Once that is created save the PAT for future use and copy that into your Octopus OCI Registry external feed for DockerHub Public Repositories alongside your Username from your DockerHub Profile:
Save the feed and you should now be able to pull Public DockerHub images.
Please also note that when you do input the Username and PAT you wont be able to search for packages in the feed test or search for the package in the step itself due to this GitHub issue so you will need to type the package in the step manually and save the step, after that the release creation will pickup the versions from those packages.
For example if using our Octopus Helm Chart you need to type octopusdeploy/octopusdeploy-helm in the step: