---
page_title: 'Attribute Custom Validators: Migrating from SDKv2 to the Framework'
description: >-
  Validations check for required syntax, types, and acceptable values. Migrate custom attribute validation functions from SDKv2 to attribute validators in the Framework.
---

# Custom Validators

You can write custom validations that give users feedback about required syntax, types, and acceptable values in your
provider. The Framework has a collection of
[predefined validators](https://github.com/hashicorp/terraform-plugin-framework-validators). Refer to
[Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined) to learn how to use them.

This page explains how to migrate attribute validation functions from SDKv2 to attribute validators in the Framework.

## SDKv2

In SDKv2, arbitrary validation logic can be applied to individual attributes by using `ValidateFunc` and/or
`ValidateDiagFunc`.

The following example shows the implementation of a validation that ensures that an integer attribute has a value
greater than one.

```go
func resourceExample() *schema.Resource {
    return &schema.Resource{
        /* ... */
        Schema: map[string]*schema.Schema{
            "attribute_example": {
                ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(1)),
                /* ... */
```

## Framework

In the Framework, you implement either type of validation by setting the `Validators` field on the `schema.Attribute`
implementation.

The following example shows how to implement a validation that ensures that an integer attribute has a value
greater than one.

```go
func (r *ThingResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        /* ... */
        Attributes: map[string]schema.Attribute{
            "attribute_example": schema.Int64Attribute{
                Validators: []validator.Int64{
                    int64validator.AtLeast(1),
                    /* ... */
```

## Migration Notes

Remember the following details when migrating from SDKv2 to the Framework.

- In SDKv2, `ValidateDiagFunc` is a field on `schema.Schema` that you can use to define custom validation functions. In
the Framework, `Validators` is a field on each `schema.Attribute` implementation that can be used for custom validations.
- Use [predefined validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined) when there is a validator that meets
your requirements.

## Example

### SDKv2

The following example shows the implementation of the `ValidateDiagFunc` field for
the `exampleResource`'s `example_attribute` attribute to validate that it's value is at least 1 (greater than zero).

```go
func exampleResource() *schema.Resource {
    return &schema.Resource{
        Schema: map[string]*schema.Schema{
            "example_attribute": {
                ValidateDiagFunc: validation.ToDiagFunc(validation.IntAtLeast(1)),
            },
        },
    }
}
```

### Framework

The following shows the same section of provider code after the migration.

This code validates that the `exampleResource`'s `example_attribute` attribute is greater than zero by using a custom `AtLeast`
validator.

```go
func (r *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "example_attribute": schema.Int64Attribute{
                Required: true,
                Validators: []validator.Int64{
                    int64validator.AtLeast(1),
                },
            },
        },
    }
}
```

This example code illustrates how you can implement your own validators.

```go
var _ validator.Int64 = atLeastValidator{}

// atLeastValidator validates that an integer Attribute's value is at least a certain value.
type atLeastValidator struct {
    min int64
}

// Description describes the validation in plain text formatting.
func (v atLeastValidator) Description(_ context.Context) string {
    return fmt.Sprintf("value must be at least %d", v.min)
}

// MarkdownDescription describes the validation in Markdown formatting.
func (v atLeastValidator) MarkdownDescription(ctx context.Context) string {
    return v.Description(ctx)
}

// Validate performs the validation.
func (v atLeastValidator) ValidateInt64(ctx context.Context, request validator.Int64Request, response *validator.Int64Response) {
    if req.ConfigValue.Int64Value() < v.min {
        response.Diagnostics.Append(validatordiag.InvalidAttributeValueDiagnostic(
            request.Path,
            v.Description(ctx),
            fmt.Sprintf("%d", req.ConfigValue.Int64Value()),
        ))
    }
}

// AtLeast returns an AttributeValidator which ensures that any configured
// attribute value:
//
//     - Is a number, which can be represented by a 64-bit integer.
//     - Is exclusively greater than the given minimum.
//
// Null (unconfigured) and unknown (known after apply) values are skipped.
func AtLeast(min int64) validator.Int64 {
    return atLeastValidator{
        min: min,
    }
}
```
