winsw/winsw · error · IOException

Cannot roll the file because matching pattern not found

Error message

Cannot roll the file because matching pattern not found

What it means

Thrown by GetNextFileNumber after all matching files have been processed and nextFileNumber is still 0. This means files were found by the glob, but none yielded a positive sequence number — the appender cannot determine what the next file number should be and refuses to roll.

Source

Thrown at src/WinSW.Core/LogAppenders.cs:651

                            if (lastNumber > nextFileNumber)
                            {
                                nextFileNumber = lastNumber;
                            }
                        }
                        else
                        {
                            throw new IOException($"File {f} does not follow the pattern provided");
                        }
                    }
                    catch (Exception e)
                    {
                        throw new IOException($"Failed to process file {f} due to error {e.Message}", e);
                    }
                }

                if (nextFileNumber == 0)
                {
                    throw new IOException("Cannot roll the file because matching pattern not found");
                }

                nextFileNumber++;
            }

            return nextFileNumber;
        }
    }

    internal sealed class StreamCopyOperation
    {
        private const int BufferSize = 1024;

        private readonly byte[] buffer;
        private readonly Stream reader;

        private int startIndex;
        private int endIndex;

View on GitHub (pinned to 1d0ee4a91b)

Solutions

  1. Rename or remove log files with #0000 sequence numbers so the appender can start from #0001
  2. Clear the log directory and let WinSW recreate rotation files from scratch
  3. Manually renumber existing rolled files starting from #0001
Defensive patterns

Strategy: validation

Validate before calling

// Before rotation, check whether any matched file has sequence #0000
string glob = $"{baseFileName}.{now:yyyyMMdd}.#*{ext}";
foreach (var f in Directory.GetFiles(baseDirectory, glob))
{
    var name = Path.GetFileNameWithoutExtension(f);
    int hash = name.IndexOf('#');
    if (hash >= 0 && int.TryParse(name.Substring(hash + 1, 4), out int n) && n <= 0)
    {
        Console.Error.WriteLine($"File {f} has non-positive sequence number #{n:D4}; rotation will fail.");
    }
}

Try / catch

try
{
    int next = GetNextFileNumber(ext, baseDirectory, baseFileName, now);
}
catch (IOException ex) when (ex.Message.Contains("matching pattern not found"))
{
    // All matched files had sequence #0000 — renumber or clear them
    eventLogger.WriteEntry($"Rotation failed: {ex.Message}. Renumber existing rolled files.");
}

Prevention

When it happens

Trigger: Directory.GetFiles returns a non-empty array, but every file's extracted 4-character post-# segment parses as 0 (or a non-positive value). When int.TryParse succeeds with value 0, the condition lastNumber > nextFileNumber (0 > 0) is false, so nextFileNumber is never incremented. After the loop, nextFileNumber == 0 triggers the throw. This happens when all matched files carry sequence number #0000 or a non-positive value.

Common situations: Log files manually numbered #0000; files created by a tool that starts at zero rather than one; a previous failed rotation that left behind #0000 files.

Related errors


AI-assisted analysis of winsw/winsw@1d0ee4a91b (2026-08-13). Data as JSON: /api/errors/62c038cedcb9c279. Report an issue: GitHub.