winsw/winsw · error · IOException

File {f} does not follow the pattern provided

Error message

File {f} does not follow the pattern provided

What it means

Thrown by RollingLogAppender.GetNextFileNumber during log file rotation when a file matching the glob pattern {baseFileName}.{datePattern}.#*{ext} is found, but the 4 characters after the '#' separator cannot be parsed as an integer. The appender expects a zero-padded sequence number in the #NNNN format to determine the next file number.

Source

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

            else
            {
                foreach (string? f in files)
                {
                    try
                    {
                        string? filenameOnly = Path.GetFileNameWithoutExtension(f);
                        int hashIndex = filenameOnly.IndexOf('#');
                        string? lastNumberAsString = filenameOnly.Substring(hashIndex + 1, 4);
                        if (int.TryParse(lastNumberAsString, out int lastNumber))
                        {
                            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;
        }

View on GitHub (pinned to 1d0ee4a91b)

Solutions

  1. Remove or rename non-conforming files from the WinSW log directory
  2. Ensure no other application writes files matching the {baseName}.{date}.#*{ext} glob into the log directory
  3. If the log directory must be shared, configure a dedicated WinSW log subdirectory
Defensive patterns

Strategy: validation

Validate before calling

// Before rotation, scan the log directory for non-conforming files
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 || hash + 4 >= name.Length || !int.TryParse(name.Substring(hash + 1, 4), out _))
    {
        Console.Error.WriteLine($"Non-conforming log file will block rotation: {f}");
    }
}

Try / catch

try
{
    int next = GetNextFileNumber(ext, baseDirectory, baseFileName, now);
}
catch (IOException ex) when (ex.Message.Contains("does not follow the pattern"))
{
    eventLogger.WriteEntry($"Skipping rotation due to non-conforming log file: {ex.Message}");
}

Prevention

When it happens

Trigger: GetNextFileNumber calls Directory.GetFiles with the glob, then for each file extracts filenameOnly.Substring(hashIndex + 1, 4) and runs int.TryParse. If those 4 characters are non-numeric the try-block throws this IOException. This happens when a file matches the glob (e.g., myservice.20240101.#abc.log) but the post-# segment is not a 4-digit number.

Common situations: A user or another process manually creates files in the log directory whose names match the glob but don't follow the #NNNN convention; leftover files from a different logging framework or an older WinSW pattern; a filename where '#' appears in an unexpected position causing the wrong 4 characters to be extracted.

Related errors


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