diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 774dce94..5830a500 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -52,6 +52,8 @@ jobs:
           - "1.3.*"
           - "1.4.*"
           - "1.5.*"
+          - "1.6.*"
+          - "1.7.*"
     steps:
       - name: Set up Go
         uses: actions/setup-go@v5
diff --git a/docs/data-sources/parameter.md b/docs/data-sources/parameter.md
index fc8100e7..4bded2d3 100644
--- a/docs/data-sources/parameter.md
+++ b/docs/data-sources/parameter.md
@@ -57,7 +57,7 @@ Optional:
 
 Optional:
 
-- `error` (String) An error message to display if the value doesn't match the provided regex.
+- `error` (String) An error message to display if the value breaks the validation rules. The following placeholders are supported: {max}, {min}, and {value}.
 - `max` (Number) The maximum of a number parameter.
 - `min` (Number) The minimum of a number parameter.
 - `monotonic` (String) Number monotonicity, either increasing or decreasing.
diff --git a/docs/resources/app.md b/docs/resources/app.md
index 631eb1ec..56800b76 100644
--- a/docs/resources/app.md
+++ b/docs/resources/app.md
@@ -77,7 +77,7 @@ resource "coder_app" "intellij" {
 - `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true.
 - `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only).
 - `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false.
-- `url` (String) A URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both.
+- `url` (String) An external url if "external=true" or a URL to be proxied to from inside the workspace. This should be of the form "http://localhost:PORT[/SUBPATH]". Either "command" or "url" may be specified, but not both.
 
 ### Read-Only
 
diff --git a/provider/app.go b/provider/app.go
index bd2eb21e..ed0ac53e 100644
--- a/provider/app.go
+++ b/provider/app.go
@@ -150,7 +150,7 @@ func appResource() *schema.Resource {
 			},
 			"url": {
 				Type: schema.TypeString,
-				Description: "A URL to be proxied to from inside the workspace. " +
+				Description: "An external url if \"external=true\" or a URL to be proxied to from inside the workspace. " +
 					"This should be of the form \"http://localhost:PORT[/SUBPATH]\". " +
 					"Either \"command\" or \"url\" may be specified, but not both.",
 				ForceNew:      true,
diff --git a/provider/parameter.go b/provider/parameter.go
index 339bb017..f4a31b7f 100644
--- a/provider/parameter.go
+++ b/provider/parameter.go
@@ -10,6 +10,7 @@ import (
 	"os"
 	"regexp"
 	"strconv"
+	"strings"
 
 	"github.com/google/uuid"
 	"github.com/hashicorp/go-cty/cty"
@@ -314,10 +315,9 @@ func parameterDataSource() *schema.Resource {
 							Optional:      true,
 						},
 						"error": {
-							Type:         schema.TypeString,
-							Optional:     true,
-							RequiredWith: []string{"validation.0.regex"},
-							Description:  "An error message to display if the value doesn't match the provided regex.",
+							Type:        schema.TypeString,
+							Optional:    true,
+							Description: "An error message to display if the value breaks the validation rules. The following placeholders are supported: {max}, {min}, and {value}.",
 						},
 					},
 				},
@@ -438,13 +438,13 @@ func (v *Validation) Valid(typ, value string) error {
 	case "number":
 		num, err := strconv.Atoi(value)
 		if err != nil {
-			return fmt.Errorf("value %q is not a number", value)
+			return takeFirstError(v.errorRendered(value), fmt.Errorf("value %q is not a number", value))
 		}
 		if !v.MinDisabled && num < v.Min {
-			return fmt.Errorf("value %d is less than the minimum %d", num, v.Min)
+			return takeFirstError(v.errorRendered(value), fmt.Errorf("value %d is less than the minimum %d", num, v.Min))
 		}
 		if !v.MaxDisabled && num > v.Max {
-			return fmt.Errorf("value %d is more than the maximum %d", num, v.Max)
+			return takeFirstError(v.errorRendered(value), fmt.Errorf("value %d is more than the maximum %d", num, v.Max))
 		}
 		if v.Monotonic != "" && v.Monotonic != ValidationMonotonicIncreasing && v.Monotonic != ValidationMonotonicDecreasing {
 			return fmt.Errorf("number monotonicity can be either %q or %q", ValidationMonotonicIncreasing, ValidationMonotonicDecreasing)
@@ -466,3 +466,23 @@ func ParameterEnvironmentVariable(name string) string {
 	sum := sha256.Sum256([]byte(name))
 	return "CODER_PARAMETER_" + hex.EncodeToString(sum[:])
 }
+
+func takeFirstError(errs ...error) error {
+	for _, err := range errs {
+		if err != nil {
+			return err
+		}
+	}
+	return xerrors.Errorf("developer error: error message is not provided")
+}
+
+func (v *Validation) errorRendered(value string) error {
+	if v.Error == "" {
+		return nil
+	}
+	r := strings.NewReplacer(
+		"{min}", fmt.Sprintf("%d", v.Min),
+		"{max}", fmt.Sprintf("%d", v.Max),
+		"{value}", value)
+	return xerrors.Errorf(r.Replace(v.Error))
+}
diff --git a/provider/parameter_test.go b/provider/parameter_test.go
index 48cf4829..e60c96f7 100644
--- a/provider/parameter_test.go
+++ b/provider/parameter_test.go
@@ -527,6 +527,20 @@ data "coder_parameter" "region" {
 			}
 			`,
 		ExpectError: regexp.MustCompile("is more than the maximum"),
+	}, {
+		Name: "NumberValidation_CustomError",
+		Config: `
+			data "coder_parameter" "region" {
+				name = "Region"
+				type = "number"
+				default = 5
+				validation {
+					max = 3
+					error = "foobar"
+				}
+			}
+			`,
+		ExpectError: regexp.MustCompile("foobar"),
 	}, {
 		Name: "NumberValidation_NotInRange",
 		Config: `
