azure-functions-core-tools icon indicating copy to clipboard operation
azure-functions-core-tools copied to clipboard

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').

Open BrunoJuchli opened this issue 8 months ago • 6 comments

🩹 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

BrunoJuchli avatar Apr 01 '25 15:04 BrunoJuchli

I experience the same issue with every minute timer schedule: '0 */1 * * * *' AzureFunctionsCoreTools v4.0.7030

Feoni4 avatar Apr 02 '25 18:04 Feoni4

Hi @BrunoJuchli ,

I've been investigating this issue.

To try and reproduce the problem, I created a similar timer-triggered function template and executed it locally using the same environment setup (including RunOnStartup = true and WEBSITE_TIME_ZONE variations like "UTC" and "SE Asia Standard Time"). I also generated logs to capture the runtime behavior.

However, I was not able to reproduce the error on my end.

Could you please review the attached functions file and log output to confirm whether my test setup aligns with yours? If I’m missing something that would help reproduce the issue more accurately, I’d really appreciate your input.

Attaching:

  • TimerTriggerFunction.txt

  • TimerTriggerLog.txt

CC: @aishwaryabh

Thank you!

TimerTriggerFunction.txt

TimerTriggerLog.txt

umangsriv avatar Apr 09 '25 07:04 umangsriv

I'm also facing this issue, but only with durable functions that I created nearly two months ago. When I add a new durable function to the same solution, it runs without error.

Edit: Renaming the timer triggered functions seems to fix the issue.

LauraKokkarinen avatar Apr 10 '25 10:04 LauraKokkarinen

@umangsriv Thanks for taking an interesting in this. I have some good and some bad news.

Thanks🙏 to the hint from @LauraKokkarinen I thought this sounds awfully like a state problem. Therefore, in my azurite instance I deleted everything "testhub" related (Blob containers, Queues and Tables). This fixed the problem for me. Even if I shutdown the functions and restart them, it still works.

The bad news: I can't help you reproduce the problem anymore... The only thing I can add:

  • before I deleted the data I was still able to reproduce the issue today
  • my code looks the same
  • my output didn't. I didn't get the Executing 'Functions.Easee-StartImportPartition...' entries, Instead I got a lot of

    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').

@umangsriv Feel free to close this if you think it's not important enough to investigate/track further.

BrunoJuchli avatar Apr 10 '25 13:04 BrunoJuchli

@umangsriv Thanks for taking an interesting in this. I have some good and some bad news.

Thanks🙏 to the hint from @LauraKokkarinen I thought this sounds awfully like a state problem. Therefore, in my azurite instance I deleted everything "testhub" related (Blob containers, Queues and Tables). This fixed the problem for me. Even if I shutdown the functions and restart them, it still works.

The bad news: I can't help you reproduce the problem anymore... The only thing I can add:

  • before I deleted the data I was still able to reproduce the issue today
  • my code looks the same
  • my output didn't. I didn't get the Executing 'Functions.Easee-StartImportPartition...' entries, Instead I got a lot of

    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').

@umangsriv Feel free to close this if you think it's not important enough to investigate/track further.

Thank you @BrunoJuchli for your detailed update. I'm glad to hear that the issue is fixed for you. I appreciate you sharing the specifics of the troubleshooting process, it’s always helpful to know what worked.

It's unfortunate that the issue can no longer be reproduced. The additional details you’ve provided about your output and code behavior are insightful. I'll make a note of them in case we encounter a similar problem in the future. Rest assured, if we do find a way to replicate this issue, I'll make it a priority to investigate further and ensure it’s resolved promptly.

If anything changes or if you’d like to revisit the matter, don’t hesitate to let me know.

Thanks again for your quick turnaround on this—your collaboration is much appreciated!

umangsriv avatar Apr 11 '25 14:04 umangsriv

I hit this same problem and the solution was what @LauraKokkarinen suggested.

My function was created last year and now I tried to update it and I hit the described error. I changed the function name and it started working. My timer was "0 */15 * * * *" but I tried to change just the timer and it did not help.

Core Tools Version: 4.0.7030 Function Runtime Version: 4.1037.0.23568 .net 8.0, isolated model

stoimen-modeshift avatar May 21 '25 15:05 stoimen-modeshift