dotnet/aspnetcore · error

Could not find an end component comment for '${start}'.

Error message

Could not find an end component comment for '${start}'.

What it means

Thrown by getComponentEndComment (ComponentDescriptorDiscovery.ts:211) when a component marker carries a prerenderId (meaning the component is prerendered and bounded by a start AND end comment), but the iterator walked through all sibling nodes without finding the matching end comment. Prerendered components emit <!--Blazor:{...prerenderId...}--> ... <!--Blazor:{prerenderId:...}--> pairs; a missing end comment means the prerendered output was truncated.

Source

Thrown at src/Components/Web.JS/src/Services/ComponentDescriptorDiscovery.ts:211

    if (node.nodeType !== Node.COMMENT_NODE) {
      continue;
    }
    if (!node.textContent) {
      continue;
    }

    const definition = blazorCommentRegularExpression.exec(node.textContent);
    const json = definition && definition[1];
    if (!json) {
      continue;
    }

    validateEndComponentPayload(json, prerenderId);

    return node as Comment;
  }

  throw new Error(`Could not find an end component comment for '${start}'.`);
}

let nextUniqueDescriptorId = 0;

function createServerComponentComment(payload: ServerComponentMarker, start: Comment, end: Comment | undefined): ServerComponentDescriptor {
  validateServerComponentPayload(payload);

  return {
    ...payload,
    uniqueId: nextUniqueDescriptorId++,
    start,
    end,
  };
}

function createWebAssemblyComponentComment(payload: WebAssemblyComponentMarker, start: Comment, end: Comment | undefined): WebAssemblyComponentDescriptor {
  validateWebAssemblyComponentPayload(payload);

View on GitHub (pinned to 294cab2f9b)

Solutions

  1. View the full raw HTML source to confirm both the start <!--Blazor:{...}--> and end <!--Blazor:{prerenderId:...}--> comments are present.
  2. Increase or remove response body size limits on proxies/load balancers for Blazor pages.
  3. Disable HTML comment stripping minifiers on Blazor routes.
  4. Check server logs for exceptions during prerender that would abort before the end marker writes.

Example fix

// before: proxy truncates streamed response
proxy_buffer_size 4k;

// after: allow full streamed SSR
proxy_buffering off;
# or size buffers to the largest prerendered page
Defensive patterns

Strategy: validation

Validate before calling

function findPairedMarkers(root: ParentNode): { start: Comment; end: Comment }[] {
  const walker = document.createTreeWalker(root, NodeFilter.SHOW_COMMENT);
  const starts = new Map<string, Comment>();
  const pairs: {start:Comment,end:Comment}[] = [];
  let n: Node | null;
  while ((n = walker.nextNode())) {
    const c = n as Comment;
    const m = /^\s*Blazor:[^{]*(?<descriptor>.*)$/.exec(c.textContent || '');
    if (!m) continue;
    const payload = JSON.parse(m.groups!.descriptor);
    if (payload.prerenderId && !starts.has(payload.prerenderId)) starts.set(payload.prerenderId, c);
    else if (payload.prerenderId) pairs.push({ start: starts.get(payload.prerenderId)!, end: c });
  }
  return pairs;
}

Type guard

function hasMatchingEndMarker(startPayload: { prerenderId?: string }, candidates: Comment[]): boolean {
  if (!startPayload.prerenderId) return true;
  return candidates.some(c => {
    try { return JSON.parse((/^\s*Blazor:[^{]*(?<d>.*)$/.exec(c.textContent||'')?.groups!.d) || '{}').prerenderId === startPayload.prerenderId; }
    catch { return false; }
  });
}

Prevention

When it happens

Trigger: A start marker with prerenderId present but its sibling subtree contains no end marker matching blazorCommentRegularExpression; happens when response streaming is cut, HTML is truncated, or an external process removed the end comment.

Common situations: Response compression or buffering that truncates long streamed SSR responses; a reverse proxy with a response body size cap; partial render due to an exception during prerendering that aborts before the end marker is emitted; CSS/HTML minifier that drops the trailing comment; custom Razor partial that does not emit the closing marker.

Related errors


AI-assisted analysis of dotnet/aspnetcore@294cab2f9b (2026-08-06). Data as JSON: /api/errors/ea5f2c7cd61c3266. Report an issue: GitHub.