diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs
index e48dd9445bfc..c05874bf536a 100644
--- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs
+++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/DiagnosticDescriptors.cs
@@ -1,6 +1,7 @@
 // Licensed to the .NET Foundation under one or more agreements.
 // The .NET Foundation licenses this file to you under the MIT license.
 
+using System.Runtime.CompilerServices;
 using Microsoft.CodeAnalysis;
 
 namespace Microsoft.AspNetCore.Analyzers;
@@ -248,4 +249,18 @@ internal static class DiagnosticDescriptors
         DiagnosticSeverity.Info,
         isEnabledByDefault: true,
         helpLinkUri: AnalyzersLink);
+
+    internal static readonly DiagnosticDescriptor InvalidRouteConstraintForParameterType = CreateDescriptor(
+        "ASP0029",
+        Usage,
+        DiagnosticSeverity.Error);
+
+    private static DiagnosticDescriptor CreateDescriptor(string id, string category, DiagnosticSeverity defaultSeverity, bool isEnabledByDefault = true, [CallerMemberName] string? name = null) => new(
+        id,
+        CreateLocalizableResourceString($"Analyzer_{name}_Title"),
+        CreateLocalizableResourceString($"Analyzer_{name}_Message"),
+        category,
+        defaultSeverity,
+        isEnabledByDefault,
+        helpLinkUri: AnalyzersLink);
 }
diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/Resources.resx b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/Resources.resx
index 8c9397f5be64..601155ef337f 100644
--- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/Resources.resx
+++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/Resources.resx
@@ -333,4 +333,10 @@
   
     If the server does not specifically reject IPv6, IPAddress.IPv6Any is preferred over IPAddress.Any usage for safety and performance reasons. See https://aka.ms/aspnetcore-warnings/ASP0028 for more details.
   
+  
+    Invalid constraint for parameter type
+  
+  
+    The constraint '{0}' on parameter '{1}' can't be used with type '{2}'
+  
 
diff --git a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/RouteHandlerAnalyzer.cs b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/RouteHandlerAnalyzer.cs
index 274bf3d4d4ce..13b793790b73 100644
--- a/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/RouteHandlerAnalyzer.cs
+++ b/src/Framework/AspNetCoreAnalyzers/src/Analyzers/RouteHandlers/RouteHandlerAnalyzer.cs
@@ -4,12 +4,14 @@
 using System;
 using System.Collections.Concurrent;
 using System.Collections.Immutable;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using Microsoft.AspNetCore.App.Analyzers.Infrastructure;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp.Syntax;
 using Microsoft.CodeAnalysis.Diagnostics;
 using Microsoft.CodeAnalysis.Operations;
+using Microsoft.CodeAnalysis.Text;
 
 namespace Microsoft.AspNetCore.Analyzers.RouteHandlers;
 
@@ -20,7 +22,8 @@ public partial class RouteHandlerAnalyzer : DiagnosticAnalyzer
 {
     private const int DelegateParameterOrdinal = 2;
 
-    public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(
+    public override ImmutableArray SupportedDiagnostics { get; } =
+    [
         DiagnosticDescriptors.DoNotUseModelBindingAttributesOnRouteHandlerParameters,
         DiagnosticDescriptors.DoNotReturnActionResultsFromRouteHandlers,
         DiagnosticDescriptors.DetectMisplacedLambdaAttribute,
@@ -28,8 +31,9 @@ public partial class RouteHandlerAnalyzer : DiagnosticAnalyzer
         DiagnosticDescriptors.RouteParameterComplexTypeIsNotParsable,
         DiagnosticDescriptors.BindAsyncSignatureMustReturnValueTaskOfT,
         DiagnosticDescriptors.AmbiguousRouteHandlerRoute,
-        DiagnosticDescriptors.AtMostOneFromBodyAttribute
-    );
+        DiagnosticDescriptors.AtMostOneFromBodyAttribute,
+        DiagnosticDescriptors.InvalidRouteConstraintForParameterType
+    ];
 
     public override void Initialize(AnalysisContext context)
     {
@@ -74,15 +78,9 @@ void DoOperationAnalysis(OperationAnalysisContext context, ConcurrentDictionary<
                     return;
                 }
 
-                IDelegateCreationOperation? delegateCreation = null;
-                foreach (var argument in invocation.Arguments)
-                {
-                    if (argument.Parameter?.Ordinal == DelegateParameterOrdinal)
-                    {
-                        delegateCreation = argument.Descendants().OfType().FirstOrDefault();
-                        break;
-                    }
-                }
+                // Already checked there are 3 arguments
+                var deleateArg = invocation.Arguments[DelegateParameterOrdinal];
+                var delegateCreation = (IDelegateCreationOperation?)deleateArg.Descendants().FirstOrDefault(static d => d is IDelegateCreationOperation);
 
                 if (delegateCreation is null)
                 {
@@ -100,6 +98,8 @@ void DoOperationAnalysis(OperationAnalysisContext context, ConcurrentDictionary<
                     return;
                 }
 
+                AnalyzeRouteConstraints(routeUsage, wellKnownTypes, context);
+
                 mapOperations.TryAdd(MapOperation.Create(invocation, routeUsage), value: default);
 
                 if (delegateCreation.Target.Kind == OperationKind.AnonymousFunction)
@@ -172,23 +172,16 @@ void DoOperationAnalysis(OperationAnalysisContext context, ConcurrentDictionary<
 
     private static bool TryGetStringToken(IInvocationOperation invocation, out SyntaxToken token)
     {
-        IArgumentOperation? argumentOperation = null;
-        foreach (var argument in invocation.Arguments)
-        {
-            if (argument.Parameter?.Ordinal == 1)
-            {
-                argumentOperation = argument;
-            }
-        }
+        var argumentOperation = invocation.Arguments[1];
 
-        if (argumentOperation?.Syntax is not ArgumentSyntax routePatternArgumentSyntax ||
-            routePatternArgumentSyntax.Expression is not LiteralExpressionSyntax routePatternArgumentLiteralSyntax)
+        if (argumentOperation.Value is not ILiteralOperation literal)
         {
             token = default;
             return false;
         }
 
-        token = routePatternArgumentLiteralSyntax.Token;
+        var syntax = (LiteralExpressionSyntax)literal.Syntax;
+        token = syntax.Token;
         return true;
     }
 
@@ -218,6 +211,133 @@ static bool IsCompatibleDelegateType(WellKnownTypes wellKnownTypes, IMethodSymbo
         }
     }
 
+    private static void AnalyzeRouteConstraints(RouteUsageModel routeUsage, WellKnownTypes wellKnownTypes, OperationAnalysisContext context)
+    {
+        foreach (var routeParam in routeUsage.RoutePattern.RouteParameters)
+        {
+            var handlerParam = GetHandlerParam(routeParam.Name, routeUsage);
+
+            if (handlerParam is null)
+            {
+                continue;
+            }
+
+            foreach (var policy in routeParam.Policies)
+            {
+                if (IsConstraintInvalidForType(policy, handlerParam.Type, wellKnownTypes))
+                {
+                    var descriptor = DiagnosticDescriptors.InvalidRouteConstraintForParameterType;
+                    var start = routeParam.Span.Start + routeParam.Name.Length + 2; // including '{' and ':'
+                    var textSpan = new TextSpan(start, routeParam.Span.End - start - 1); // excluding '}'
+                    var location = Location.Create(context.FilterTree, textSpan);
+                    var diagnostic = Diagnostic.Create(descriptor, location, policy.AsMemory(1), routeParam.Name, handlerParam.Type.ToString());
+
+                    context.ReportDiagnostic(diagnostic);
+                }
+            }
+        }
+    }
+
+    private static bool IsConstraintInvalidForType(string policy, ITypeSymbol type, WellKnownTypes wellKnownTypes)
+    {
+        if (policy.EndsWith(")", StringComparison.Ordinal)) // Parameterized constraint
+        {
+            var braceIndex = policy.IndexOf('(');
+
+            if (braceIndex == -1)
+            {
+                return false;
+            }
+
+            var constraint = policy.AsSpan(1, braceIndex - 1);
+
+            return constraint switch
+            {
+                "length" or "minlength" or "maxlength" or "regex" when type.SpecialType is not SpecialType.System_String => true,
+                "min" or "max" or "range" when !IsIntegerType(type) && !IsNullableIntegerType(type) => true,
+                _ => false
+            };
+        }
+        else // Simple constraint
+        {
+            var constraint = policy.AsSpan(1);
+
+            return constraint switch
+            {
+                "int" when !IsIntegerType(type) && !IsNullableIntegerType(type) => true,
+                "bool" when !IsValueTypeOrNullableValueType(type, SpecialType.System_Boolean) => true,
+                "datetime" when !IsValueTypeOrNullableValueType(type, SpecialType.System_DateTime) => true,
+                "double" when !IsValueTypeOrNullableValueType(type, SpecialType.System_Double) => true,
+                "guid" when !IsGuidType(type, wellKnownTypes) && !IsNullableGuidType(type, wellKnownTypes) => true,
+                "long" when !IsLongType(type) && !IsNullableLongType(type) => true,
+                "decimal" when !IsValueTypeOrNullableValueType(type, SpecialType.System_Decimal) => true,
+                "float" when !IsValueTypeOrNullableValueType(type, SpecialType.System_Single) => true,
+                "alpha" when type.SpecialType is not SpecialType.System_String => true,
+                "file" or "nonfile" when type.SpecialType is not SpecialType.System_String => true,
+                _ => false
+            };
+        }
+    }
+
+    private static IParameterSymbol? GetHandlerParam(string name, RouteUsageModel routeUsage)
+    {
+        foreach (var param in routeUsage.UsageContext.Parameters)
+        {
+            if (param.Name.Equals(name, StringComparison.Ordinal))
+            {
+                return (IParameterSymbol)param;
+            }
+        }
+
+        return null;
+    }
+
+    private static bool IsGuidType(ITypeSymbol type, WellKnownTypes wellKnownTypes)
+    {
+        return type.Equals(wellKnownTypes.Get(WellKnownType.System_Guid), SymbolEqualityComparer.Default);
+    }
+
+    private static bool IsIntegerType(ITypeSymbol type)
+    {
+        return type.SpecialType >= SpecialType.System_SByte && type.SpecialType <= SpecialType.System_UInt64;
+    }
+
+    private static bool IsLongType(ITypeSymbol type)
+    {
+        return type.SpecialType is SpecialType.System_Int64 or SpecialType.System_UInt64;
+    }
+
+    private static bool IsNullableGuidType(ITypeSymbol type, WellKnownTypes wellKnownTypes)
+    {
+        return IsNullableType(type, out var namedType) && IsGuidType(namedType.TypeArguments[0], wellKnownTypes);
+    }
+
+    private static bool IsNullableIntegerType(ITypeSymbol type)
+    {
+        return IsNullableType(type, out var namedType) && IsIntegerType(namedType.TypeArguments[0]);
+    }
+
+    private static bool IsNullableLongType(ITypeSymbol type)
+    {
+        return IsNullableType(type, out var namedType) && IsLongType(namedType.TypeArguments[0]);
+    }
+
+    public static bool IsNullableType(ITypeSymbol type, [NotNullWhen(true)] out INamedTypeSymbol? namedType)
+    {
+        namedType = type as INamedTypeSymbol;
+        return namedType != null && namedType.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T;
+    }
+
+    private static bool IsNullableValueType(ITypeSymbol type, SpecialType specialType)
+    {
+        return IsNullableType(type, out var namedType) && namedType.TypeArguments[0].SpecialType == specialType;
+    }
+
+    private static bool IsValueTypeOrNullableValueType(ITypeSymbol type, SpecialType specialType)
+    {
+        return type.SpecialType == specialType || IsNullableValueType(type, specialType);
+    }
+
     private record struct MapOperation(IOperation? Builder, IInvocationOperation Operation, RouteUsageModel RouteUsageModel)
     {
         public static MapOperation Create(IInvocationOperation operation, RouteUsageModel routeUsageModel)
diff --git a/src/Framework/AspNetCoreAnalyzers/test/Extensions/CSharpAnalyzerTestExtensions.cs b/src/Framework/AspNetCoreAnalyzers/test/Extensions/CSharpAnalyzerTestExtensions.cs
new file mode 100644
index 000000000000..a341d4758b9d
--- /dev/null
+++ b/src/Framework/AspNetCoreAnalyzers/test/Extensions/CSharpAnalyzerTestExtensions.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.AspNetCore.Analyzers.Verifiers;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp.Testing;
+using Microsoft.CodeAnalysis.Diagnostics;
+using Microsoft.CodeAnalysis.Testing;
+
+namespace Microsoft.AspNetCore.Analyzers;
+
+public static class CSharpAnalyzerTestExtensions
+{
+    extension(CSharpAnalyzerTest)
+        where TAnalyzer : DiagnosticAnalyzer, new()
+        where TVerifier : IVerifier, new()
+    {
+        public static CSharpAnalyzerTest Create([StringSyntax("C#-test")] string source, params ReadOnlySpan expectedDiagnostics)
+        {
+            var test = new CSharpAnalyzerTest
+            {
+                TestCode = source.ReplaceLineEndings(),
+                // We need to set the output type to an exe to properly
+                // support top-level programs in the tests. Otherwise,
+                // the test infra will assume we are trying to build a library.
+                TestState = { OutputKind = OutputKind.ConsoleApplication },
+                ReferenceAssemblies = CSharpAnalyzerVerifier.GetReferenceAssemblies(),
+            };
+
+            test.ExpectedDiagnostics.AddRange(expectedDiagnostics);
+            return test;
+        }
+    }
+
+    public static CSharpAnalyzerTest WithSource(this CSharpAnalyzerTest test, [StringSyntax("C#-test")] string source)
+        where TAnalyzer : DiagnosticAnalyzer, new()
+        where TVerifier : IVerifier, new()
+    {
+        test.TestState.Sources.Add(source);
+        return test;
+    }
+}
diff --git a/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DetectMismatchedParameterOptionalityTest.cs b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DetectMismatchedParameterOptionalityTest.cs
index ab0c98cae9e0..cec926d5fe9c 100644
--- a/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DetectMismatchedParameterOptionalityTest.cs
+++ b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/DetectMismatchedParameterOptionalityTest.cs
@@ -300,7 +300,7 @@ public async Task OptionalRouteParamRequiredArgument_WithRegexConstraint_Produce
 using Microsoft.AspNetCore.Builder;
 
 var app = WebApplication.Create();
-app.MapGet(""/hello/{age:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)?}"", ({|#0:int age|}) => $""Age: {age}"");
+app.MapGet(""/hello/{age:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)?}"", ({|#0:string age|}) => $""Age: {age}"");
 ";
 
         var fixedSource = @"
@@ -308,7 +308,7 @@ public async Task OptionalRouteParamRequiredArgument_WithRegexConstraint_Produce
 using Microsoft.AspNetCore.Builder;
 
 var app = WebApplication.Create();
-app.MapGet(""/hello/{age:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)?}"", (int? age) => $""Age: {age}"");
+app.MapGet(""/hello/{age:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)?}"", (string? age) => $""Age: {age}"");
 ";
         var expectedDiagnostic = new DiagnosticResult(DiagnosticDescriptors.DetectMismatchedParameterOptionality).WithArguments("age").WithLocation(0);
 
diff --git a/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/InvalidRouteConstraintForParameterType.cs b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/InvalidRouteConstraintForParameterType.cs
new file mode 100644
index 000000000000..988dc0544c09
--- /dev/null
+++ b/src/Framework/AspNetCoreAnalyzers/test/RouteHandlers/InvalidRouteConstraintForParameterType.cs
@@ -0,0 +1,355 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Data;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.Testing;
+
+using CSTest = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerTest<
+    Microsoft.AspNetCore.Analyzers.RouteHandlers.RouteHandlerAnalyzer,
+    Microsoft.CodeAnalysis.Testing.DefaultVerifier>;
+
+namespace Microsoft.AspNetCore.Analyzers.RouteHandlers;
+
+public class InvalidRouteConstraintForParameterType
+{
+    private const string Program = $$$"""
+        using Microsoft.AspNetCore.Builder;
+
+        var webApp = WebApplication.Create();
+        """;
+
+    private static string[] IntConstraints = ["int", "min(10)", "max(10)", "range(1,10)"];
+    private static string[] IntTypes = ["byte", "sbyte", "short", "ushort", "int", "uint", "long", "ulong"];
+
+    public static TheoryData MapMethods { get; } = ["Map", "MapDelete", "MapFallback", "MapGet", "MapPatch", "MapPost", "MapPut"];
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task LambdaWithValidConstraint_NoDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetValidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i++}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{{{constraint}}}}", ({{{type}}} param) => { });
+                    }
+                }
+                """);
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task LambdaWithInvalidConstraint_HasDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetInvalidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{|#{{{i}}}:{{{constraint}}}|}}", ({{{type}}} param) => { });
+                    }
+                }
+                """);
+
+            test.ExpectedDiagnostics.Add(CreateDiagnostic(constraint, "param", type, location: i++));
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task LocalFunctionWithValidConstraint_NoDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetValidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i++}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{{{constraint}}}}", LocalFunction);
+                
+                        string LocalFunction({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task LocalFunctionWithInvalidConstraint_HasDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetInvalidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{|#{{{i}}}:{{{constraint}}}|}}", LocalFunction);
+                
+                        string LocalFunction({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+
+            test.ExpectedDiagnostics.Add(CreateDiagnostic(constraint, "param", type, location: i++));
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task InstanceMethodWithValidConstraint_NoDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetValidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i++}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        var handler = new Handler();
+                        app.{{{methodName}}}(@"/api/{param:{{{constraint}}}}", handler.Handle);
+                    }
+                
+                    private class Handler
+                    {
+                        public string Handle({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task InstanceMethodWithInvalidConstraint_HasDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetInvalidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        var handler = new Handler();
+                        app.{{{methodName}}}(@"/api/{param:{|#{{{i}}}:{{{constraint}}}|}}", handler.Handle);
+                    }
+                
+                    private class Handler
+                    {
+                        public string Handle({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+
+            test.ExpectedDiagnostics.Add(CreateDiagnostic(constraint, "param", type, location: i++));
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task StaticMethodWithValidConstraint_NoDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetValidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i++}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{{{constraint}}}}", Handler.Handle);
+                    }
+                
+                    private static class Handler
+                    {
+                        public static string Handle({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    [Theory]
+    [MemberData(nameof(MapMethods))]
+    public async Task StaticMethodWithInvalidConstraint_HasDiagnostics(string methodName)
+    {
+        // Arrange
+        var test = CSTest.Create(Program);
+        var i = 0;
+
+        foreach (var (constraint, type) in GetInvalidCombinations())
+        {
+            test.WithSource($$$"""
+                using System;
+                using Microsoft.AspNetCore.Builder;
+
+                public static class Endpoints{{{i}}}
+                {
+                    public static void Map(WebApplication app)
+                    {
+                        app.{{{methodName}}}(@"/api/{param:{|#{{{i}}}:{{{constraint}}}|}}", Handler.Handle);
+                    }
+                
+                    public static class Handler
+                    {
+                        public static string Handle({{{type}}} param) => param.ToString();
+                    }
+                }
+                """);
+
+            test.ExpectedDiagnostics.Add(CreateDiagnostic(constraint, "param", type, location: i++));
+        }
+
+        // Act & Assert
+        await test.RunAsync();
+    }
+
+    public static IEnumerable<(string constraint, string type)> GetValidCombinations()
+    {
+        yield return ("bool", "bool");
+        yield return ("datetime", "DateTime");
+        yield return ("decimal", "decimal");
+        yield return ("double", "double");
+        yield return ("float", "float");
+        yield return ("guid", "Guid");
+
+        yield return ("alpha", "string");
+        yield return ("file", "string");
+        yield return ("nonfile", "string");
+
+        yield return ("length(10)", "string");
+        yield return ("minlength(10)", "string");
+        yield return ("maxlength(10)", "string");
+        yield return (@"regex(\w+)", "string");
+
+        yield return ("long", "long");
+        yield return ("long", "ulong");
+
+        foreach (var constraint in IntConstraints)
+        {
+            foreach (var type in IntTypes)
+            {
+                yield return (constraint, type);
+            }
+        }
+    }
+
+    public static IEnumerable<(string constraint, string type)> GetInvalidCombinations()
+    {
+        yield return ("bool", "int");
+        yield return ("datetime", "int");
+        yield return ("decimal", "int");
+        yield return ("double", "int");
+        yield return ("float", "int");
+        yield return ("guid", "int");
+
+        yield return ("alpha", "int");
+        yield return ("file", "int");
+        yield return ("nonfile", "int");
+
+        yield return ("length(10)", "int");
+        yield return ("minlength(10)", "int");
+        yield return ("maxlength(10)", "int");
+        yield return (@"regex(\w+)", "int");
+
+        yield return ("long", "byte");
+        yield return ("long", "sbyte");
+        yield return ("long", "short");
+        yield return ("long", "ushort");
+        yield return ("long", "int");
+        yield return ("long", "uint");
+
+        foreach (var constraint in IntConstraints)
+        {
+            yield return (constraint, "string");
+        }
+    }
+
+    private static DiagnosticResult CreateDiagnostic(string constraint, string parameter, string typeName, int location = 0)
+    {
+        return new DiagnosticResult(DiagnosticDescriptors.InvalidRouteConstraintForParameterType)
+            .WithArguments(constraint, parameter, typeName)
+            .WithLocation(location);
+    }
+}
diff --git a/src/Shared/RoslynUtils/WellKnownTypeData.cs b/src/Shared/RoslynUtils/WellKnownTypeData.cs
index a64dd1a426e8..981fd3d50150 100644
--- a/src/Shared/RoslynUtils/WellKnownTypeData.cs
+++ b/src/Shared/RoslynUtils/WellKnownTypeData.cs
@@ -35,6 +35,7 @@ public enum WellKnownType
         System_Collections_IEnumerable,
         System_DateOnly,
         System_DateTimeOffset,
+        System_Guid,
         System_IO_Stream,
         System_IO_Pipelines_PipeReader,
         System_IFormatProvider,
@@ -159,6 +160,7 @@ public enum WellKnownType
         "System.Collections.IEnumerable",
         "System.DateOnly",
         "System.DateTimeOffset",
+        "System.Guid",
         "System.IO.Stream",
         "System.IO.Pipelines.PipeReader",
         "System.IFormatProvider",