Skip to content

The listener for function '(...)' was unable to start. System.Private.CoreLib: The UTC time represented when the offset is applied must be between year 0 and 10,000. (Parameter 'offset'). #4348

Open
@BrunoJuchli

Description

@BrunoJuchli

🩹 Workaround

Tip

In my case it helped to delete everything named "TestHub*" or "testhub*" from my local Azurite instance.
With everything I mean Blob Containers, Queues and Tables.
You can do this via Microsoft Azure Storage Explorer.

Warning

While I haven't lost any important data by deleting the testhub stuff from azurite, your mileage may vary.

Version

Core Tools Version: 4.0.7030
Function Runtime Version: 4.1037.0.23568

Description

I have 30 timer triggered functions that I generate with a template, that is, they are identical apart from a number in their names and the timer trigger. All the timer triggers look like this:

[TimerTrigger("0 * * * *", RunOnStartup = true)] TimerInfo timer
[TimerTrigger("2 * * * *", RunOnStartup = true)] TimerInfo timer
[TimerTrigger("4 * * * *", RunOnStartup = true)] TimerInfo timer

and so on (that is there's a function being triggered for every other minute of the hour - not that they don't do the exact same thing, so having a function that runs every minute would not achieve my goal,here).

For most of the functions I get an error like:

The listener for function 'Functions.Easee-StartImportPartition44' was unable to start. System.Private.CoreLib: The UTC time represented when the offset is applied must be between year 0 and 10,000. (Parameter 'offset').

And they are never executed.

For a few functions I don't, get an error. Example:

The next 5 occurrences of the 'Easee-StartImportPartition48' schedule (Cron: '48 * * * *') will be:
04/01/2025 17:48:00+02:00 (04/01/2025 15:48:00Z)
04/01/2025 18:48:00+02:00 (04/01/2025 16:48:00Z)
04/01/2025 19:48:00+02:00 (04/01/2025 17:48:00Z)
etc.

These are executed.
It's only the functions for minutes 48, 50, 52 that work. 00-46 and 54-58 don't.

If I retry the same thing 10 minutes later, it's the same behavior (the same 3 functions that get executed).

Steps to Reproduce

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated> 
//------------------------------------------------------------------------------

using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;

public static partial class TimedTriggerStartPartitionImportFunctions
{
    [Function("Easee-StartImportPartition0")]
    public static Task StartImportPartition0(
            [TimerTrigger("0 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition0));
        return StartImportPartition(
            0,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition2")]
    public static Task StartImportPartition2(
            [TimerTrigger("2 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition2));
        return StartImportPartition(
            2,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition4")]
    public static Task StartImportPartition4(
            [TimerTrigger("4 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition4));
        return StartImportPartition(
            4,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition6")]
    public static Task StartImportPartition6(
            [TimerTrigger("6 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition6));
        return StartImportPartition(
            6,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition8")]
    public static Task StartImportPartition8(
            [TimerTrigger("8 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition8));
        return StartImportPartition(
            8,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition10")]
    public static Task StartImportPartition10(
            [TimerTrigger("10 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition10));
        return StartImportPartition(
            10,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition12")]
    public static Task StartImportPartition12(
            [TimerTrigger("12 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition12));
        return StartImportPartition(
            12,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition14")]
    public static Task StartImportPartition14(
            [TimerTrigger("14 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition14));
        return StartImportPartition(
            14,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition16")]
    public static Task StartImportPartition16(
            [TimerTrigger("16 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition16));
        return StartImportPartition(
            16,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition18")]
    public static Task StartImportPartition18(
            [TimerTrigger("18 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition18));
        return StartImportPartition(
            18,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition20")]
    public static Task StartImportPartition20(
            [TimerTrigger("20 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition20));
        return StartImportPartition(
            20,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition22")]
    public static Task StartImportPartition22(
            [TimerTrigger("22 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition22));
        return StartImportPartition(
            22,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition24")]
    public static Task StartImportPartition24(
            [TimerTrigger("24 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition24));
        return StartImportPartition(
            24,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition26")]
    public static Task StartImportPartition26(
            [TimerTrigger("26 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition26));
        return StartImportPartition(
            26,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition28")]
    public static Task StartImportPartition28(
            [TimerTrigger("28 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition28));
        return StartImportPartition(
            28,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition30")]
    public static Task StartImportPartition30(
            [TimerTrigger("30 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition30));
        return StartImportPartition(
            30,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition32")]
    public static Task StartImportPartition32(
            [TimerTrigger("32 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition32));
        return StartImportPartition(
            32,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition34")]
    public static Task StartImportPartition34(
            [TimerTrigger("34 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition34));
        return StartImportPartition(
            34,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition36")]
    public static Task StartImportPartition36(
            [TimerTrigger("36 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition36));
        return StartImportPartition(
            36,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition38")]
    public static Task StartImportPartition38(
            [TimerTrigger("38 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition38));
        return StartImportPartition(
            38,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition40")]
    public static Task StartImportPartition40(
            [TimerTrigger("40 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition40));
        return StartImportPartition(
            40,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition42")]
    public static Task StartImportPartition42(
            [TimerTrigger("42 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition42));
        return StartImportPartition(
            42,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition44")]
    public static Task StartImportPartition44(
            [TimerTrigger("44 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition44));
        return StartImportPartition(
            44,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition46")]
    public static Task StartImportPartition46(
            [TimerTrigger("46 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition46));
        return StartImportPartition(
            46,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition48")]
    public static Task StartImportPartition48(
            [TimerTrigger("48 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition48));
        return StartImportPartition(
            48,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition50")]
    public static Task StartImportPartition50(
            [TimerTrigger("50 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition50));
        return StartImportPartition(
            50,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition52")]
    public static Task StartImportPartition52(
            [TimerTrigger("52 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition52));
        return StartImportPartition(
            52,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition54")]
    public static Task StartImportPartition54(
            [TimerTrigger("54 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition54));
        return StartImportPartition(
            54,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition56")]
    public static Task StartImportPartition56(
            [TimerTrigger("56 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition56));
        return StartImportPartition(
            56,
            starter,
            logger);
    }

    [Function("Easee-StartImportPartition58")]
    public static Task StartImportPartition58(
            [TimerTrigger("58 * * * *", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition58));
        return StartImportPartition(
            58,
            starter,
            logger);
    }
}
#>


using Microsoft.Azure.Functions.Worker;
using Microsoft.DurableTask.Client;

public static partial class TimedTriggerStartPartitionImportFunctions
{
<#  

    for(var i = 0; i < PartitionSize; i+=2)
    {
#>

    [Function("Easee-StartImportPartition<#= i #>")]
    public static Task StartImportPartition<#= i #>(
            [TimerTrigger("<#= CreateCronExpressionForPartition(i) #>", RunOnStartup = true)] TimerInfo timer,
            [DurableClient] DurableTaskClient starter,
            FunctionContext executionContext)
    {
        var logger = executionContext.GetLogger(
            nameof(StartImportPartition<#= i #>));
        return StartImportPartition(
            <#= i #>,
            starter,
            logger);
    }
<#    
    }

#>
}

Alongside with that, use the following c# code:

public static partial class TimedTriggerStartPartitionImportFunctions
{
    private static Task StartImportPartition(
        int partition,
        DurableTaskClient starter,
        ILogger log)
    {
        var instanceId = FormattableString.Invariant($"Part{partition}");

        return DurableOrchestrationFunctionStarter.StartNewIfNotStartedAsync(
            functionName: OrchestrationFunction.FunctionName,
            argument: partition,
            instanceId: instanceId,
            starter,
            log);
    }
}

public class OrchestrationFunction
{
    public const string FunctionName = nameof(OrchestrationFunction);

    [Function(FunctionName)]
    public Task OrchestrateImportPartition(
        [OrchestrationTrigger] TaskOrchestrationContext context)
    {
        var log = context.CreateReplaySafeLogger(FunctionName);
        var partitionNumber = context.GetInput<int>();
        log.LogTrace("done partition {0}", partitionNumber);
    }
}

public static class DurableOrchestrationFunctionStarter
{
    public static async Task StartNewIfNotStartedAsync<TArg>(
        string functionName,
        TArg argument,
        string instanceId,
        DurableTaskClient starter,
        ILogger log)
    {
        var status = await starter
            .GetInstanceAsync(instanceId)
            .ConfigureAwait(false);

        if (status != null
            && DurableFunctionIsRunningDeterminer.IsRunning(status.RuntimeStatus))
        {
            log.LogError(
                "Durable function '{0}' of partition '{1}' is still running. Status: {2}. Waiting for next cycle.",
                functionName,
                instanceId,
                status.RuntimeStatus);
        }
        else
        {
            var assignedInstanceId = await starter.ScheduleNewOrchestrationInstanceAsync(
                functionName,
                argument,
                new StartOrchestrationOptions
                {
                    InstanceId = instanceId,
                });

            if (assignedInstanceId != instanceId)
            {
                log.LogCritical(
                    $"When starting the function '{0}' system overrode the manually assigned instance id '{1}' with '{2}'. Functions could be executed in parallel.",
                    functionName,
                    instanceId,
                    assignedInstanceId);
            }
            else
            {
                log.LogTrace(
                    "Started {0} with instance id '{1}'",
                    functionName,
                    instanceId);
            }
        }
    }
}

Debug this locally.

Other Things Tried

From what I read, it's possible that similar errors occur depending on the timezone setting. I have tried setting the timezone to

  • "WEBSITE_TIME_ZONE": "UTC" and to
  • "WEBSITE_TIME_ZONE": "SE Asia Standard Time"

to no avail in:

  • host.json
  • local.settings.json (root level and under "Values":
  • appsettings.json

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions