microsoft/aspire · error · ArgumentNullException

Value cannot be null. (Parameter 'logger')

Error message

Value cannot be null. (Parameter 'logger')

What it means

The ContainerRuntimeBase protected constructor guards its ILogger<TLogger> dependency with ArgumentNullException. A null logger means the runtime implementation (Docker/Podman) was constructed without required infrastructure, so it cannot log container operations.

Solutions

  1. Register and resolve ILogger<TLogger> from DI when constructing the runtime.
  2. In tests, use NullLogger<TLogger>.Instance instead of null.
  3. Fix the composition root so the runtime is created through the service provider.

Example fix

// before
new DockerRuntime(null!, processRunner);
// after
new DockerRuntime(NullLogger<DockerRuntime>.Instance, processRunner);
Defensive patterns

Strategy: type-guard

Validate before calling

if (logger is null) throw new InvalidOperationException("ContainerRuntimeBase requires a non-null ILogger<TLogger>");

Type guard

static bool CanCreateRuntime(ILogger<DockerRuntime>? logger, IProcessRunner? runner) => logger is not null && runner is not null;

Try / catch

try { runtime = new DockerRuntime(logger, processRunner); }
catch (ArgumentNullException ex) when (ex.ParamName is "logger" or "processRunner")
{
    logger ??= NullLogger<DockerRuntime>.Instance;
    runtime = new DockerRuntime(logger, processRunner!);
}

Prevention

When it happens

Trigger: Constructing a concrete ContainerRuntimeBase subclass (e.g. DockerRuntime) passing null for the logger parameter.

Common situations: Manual instantiation in tests with null! placeholders; DI container not registering ILogger<T> for the runtime type; custom runtime subclass forgetting to resolve the logger from the service provider.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/4b523863abb75fa6. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/Publishing/ContainerRuntimeBase.cs:28

using System.Text.Json.Serialization;
using Aspire.Hosting.ApplicationModel;
using Aspire.Hosting.Dcp.Process;
using Microsoft.Extensions.Logging;

namespace Aspire.Hosting.Publishing;

/// <summary>
/// Base class for container runtime implementations that provides common process execution,
/// logging, and error handling patterns.
/// </summary>
internal abstract class ContainerRuntimeBase<TLogger> : IContainerRuntime where TLogger : class
{
    private readonly ILogger<TLogger> _logger;
    private readonly IProcessRunner _processRunner;

    protected ContainerRuntimeBase(ILogger<TLogger> logger, IProcessRunner processRunner)
    {
        _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        _processRunner = processRunner ?? throw new ArgumentNullException(nameof(processRunner));
    }

    /// <summary>
    /// Gets the logger instance for use in derived classes.
    /// </summary>
    protected ILogger<TLogger> Logger => _logger;

    /// <summary>
    /// Gets the process runner used for container runtime commands.
    /// </summary>
    protected IProcessRunner ProcessRunner => _processRunner;

    /// <summary>
    /// Gets the name of the container runtime executable (e.g., "docker", "podman").
    /// </summary>
    protected abstract string RuntimeExecutable { get; }

View on GitHub (pinned to 25830f84bd)