---
page_title: 'Attribute predefined validators: Migrating from SDKv2 to the Framework'
description: >-
  Validations check required syntax, types, and acceptable values.
  Migrate the predefined ConflictsWith, ExactlyOneOf, AtLeastOneOf and RequiredWith validators to the Framework.
---

# Validators - Predefined

Attribute validators ensure that attributes do or do not contain specific values. You can use predefined validators for
many use cases, or implement custom validators. Refer to [Schemas - Validators](/terraform/plugin/framework/handling-data/schemas#validators) in
the Framework documentation for details. Refer to the
[Attributes - Custom Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-custom) page in this guide to learn how to
implement custom validators.

The following table describes the mapping between predefined validators in SDKv2 and the Framework. You should use an
attribute validator for [per-attribute validation](/terraform/plugin/framework/validation#attribute-validation), or a
[data source validator](/terraform/plugin/framework/data-sources/validate-configuration),
[provider validator](/terraform/plugin/framework/providers/validate-configuration) or
[resource validator](/terraform/plugin/framework/resources/validate-configuration) for declaring validation at the level of the
data source, provider or resource, respectively.

| SDK Attribute Field | Framework Attribute Validator   | Framework Data Source Validator                                                                                                                              | Framework Provider Validator                                                                                                                             | Framework Resource Validator                                                                                                                             |
|---------------------|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| AtLeastOneOf        | {TYPE}validator.AtLeastOneOf()  | [datasourcevalidator.AtLeastOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator#AtLeastOneOf)         | [providervalidator.AtLeastOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator#AtLeastOneOf)         | [resourcevalidator.AtLeastOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator#AtLeastOneOf)         |
| ConflictsWith       | {TYPE}validator.ConflictsWith() | [datasourcevalidator.Conflicting()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator#Conflicting)           | [providervalidator.Conflicting()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator#Conflicting)           | [resourcevalidator.Conflicting()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator#Conflicting)           |
| ExactlyOneOf        | {TYPE}validator.ExactlyOneOf()  | [datasourcevalidator.ExactlyOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator#ExactlyOneOf)         | [providervalidator.ExactlyOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator#ExactlyOneOf)         | [resourcevalidator.ExactlyOneOf()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator#ExactlyOneOf)         |
| RequiredWith        | {TYPE}validator.AlsoRequires()  | [datasourcevalidator.RequiredTogether()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator#RequiredTogether) | [providervalidator.RequiredTogether()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator#RequiredTogether) | [resourcevalidator.RequiredTogether()](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator#RequiredTogether) |

This page explains how to migrate a predefined validator from SDKv2 to the Framework.

## SDKv2

In SDKv2, the `ConflictsWith`, `ExactlyOneOf`, `AtLeastOneOf`, and `RequiredWith` fields on an attribute's
`schema.Schema` struct perform predefined validations on the list of attributes set for these fields.

```go
func resourceExample() *schema.Resource {
    return &schema.Resource{
        /* ... */
        Schema: map[string]*schema.Schema{
            "attribute_example": {
                ConflictsWith:  []string{ /* ... */ },
                ExactlyOneOf:   []string{ /* ... */ },
                AtLeastOneOf:   []string{ /* ... */ },
                RequiredWith:   []string{ /* ... */ },
            /* ... */
```
## Framework

In the Framework, you implement either type of validation by setting the `Validators` field on the `schema.Attribute`
implementation. Validators that perform the same checks as the
predefined validators in SDKv2 are
[available for the Framework](https://github.com/hashicorp/terraform-plugin-framework-validators). If the predefined
validators do not meet your needs, you must define
[custom validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-custom).

```go
func (r *resourceExample) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        /* ... */
        Attributes: map[string]schema.Attribute{
            "attribute_example": schema.StringAttribute{
                Validators: []validator.String{
                    stringvalidator.ConflictsWith( /* ... */ ),
                    /* ... */
```

Configuration validators can also be defined for
[providers](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/providervalidator),
[resources](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/resourcevalidator) and
[data sources](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/datasourcevalidator) by
implementing `ProviderWithConfigValidators`, `ResourceWithConfigValidators`, and `DataSourceWithConfigValidators`
interfaces, respectively.

```go
func (r *resourceExample) ConfigValidators(ctx context.Context) []resource.ConfigValidator {
    return []resource.ConfigValidator{
        resourcevalidator.Conflicting(
            /* ... */
        ),
        /* ... */
```

## 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 validation functions. In SDKv2,
there are also built-in validations. For example, `ConflictsWith` is a field on the `schema.Schema` struct in SDKv2. In
the Framework, `Validators` is a field on each `schema.Attribute` implementation.
- Validators replicating the behavior of `ConflictsWith`, `ExactlyOneOf`, `AtLeastOneOf`, and `RequiredWith` in SDKv2 are
available for the Framework in each of the type-specific packages of
[terraform-plugin-framework-validators](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators).
- Define [custom validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-custom) when the predefined validators do not meet
your requirements.

## Example

### SDKv2

The following example shows the implementation of the `ConflictsWith` field on the
provider's `example_block` block's `example_attribute_one` attribute.
This validator checks that the provider does not use the `example_attribute_one` attribute
when the `example_attribute_four` is being used. The example also uses the `RequiredWith` field to ensure that the
`example_attribute_two` attribute is configured when `example_attribute_one` is, and that the
`example_attribute_three` attribute is configured when `example_attribute_two` is.

```go
func New() (*schema.Provider, error) {
    return &schema.Provider{
        Schema: map[string]*schema.Schema{
            "example_block": {
                Elem: &schema.Resource{
                    Schema: map[string]*schema.Schema{
                        "example_attribute_one": {
                            ConflictsWith: []string{"example_block.0.example_attribute_four"},
                            /* ... */
                        },
                        "example_attribute_two": {
                            RequiredWith: []string{"example_block.0.example_attribute_one"},
                            /* ... */
                        },
                        "example_attribute_three": {
                            RequiredWith: []string{"example_block.0.example_attribute_two"},
                            /* ... */
                        },
                        "example_attribute_four": {
                            ConflictsWith: []string{
                                "example_block.0.example_attribute_one",
                                "example_block.0.example_attribute_two",
                                "example_block.0.example_attribute_three",
                            },
                            /* ... */
                        },
                    },
                },
            },
        },
    }, nil
}
```

### Framework

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

This code implements the `ConflictsWith` and `AlsoRequires` validators with the Framework. The validators are configured
via the `Validators` field of the provider's `example_block` block's attribute schema.

```go
func (p *TlsProvider) Schema(_ context.Context, _ provider.SchemaRequest, resp *provider.SchemaResponse) {
    resp.Schema = schema.Schema{
        Blocks: map[string]schema.Block{
            "example_block": schema.ListNestedBlock{
                NestedObject: schema.NestedBlockObject{
                    Attributes: map[string]schema.Attribute{
                        "example_attribute_one": schema.StringAttribute{
                            Validators: []validator.String{
                                stringvalidator.ConflictsWith(path.MatchRelative().AtParent().AtName("example_attribute_four")),
                            },
                            /* ... */
                        },
                        "example_attribute_two": schema.StringAttribute{
                            Validators: []validator.String{
                                stringvalidator.AlsoRequires(path.MatchRelative().AtParent().AtName("example_attribute_one")),
                            },
                            /* ... */
                        },
                        "example_attribute_three": schema.StringAttribute{
                            Validators: []validator.String{
                                stringvalidator.AlsoRequires(path.MatchRelative().AtParent().AtName("example_attribute_two")),
                            },
                            /* ... */
                        },
                        "example_attribute_four": schema.BoolAttribute{
                            Validators: []validator.Bool{
                                boolvalidator.ConflictsWith(
                                    path.MatchRelative().AtParent().AtName("example_attribute_one"),
                                    path.MatchRelative().AtParent().AtName("example_attribute_two"),
                                    path.MatchRelative().AtParent().AtName("example_attribute_three"),
                                ),
                            },
                            /* ... */
                        },
                    },
                },
            },
    }
}
```
